Chinaunix首页 | 论坛 | 博客
  • 博客访问: 250367
  • 博文数量: 101
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 95
  • 用 户 组: 普通用户
  • 注册时间: 2011-12-12 12:35
文章分类

全部博文(101)

文章存档

2016年(5)

2015年(16)

2014年(37)

2013年(32)

2012年(8)

2011年(3)

我的朋友

分类: LINUX

2013-12-03 17:37:57

原文地址:sysfs文件系统之建立文件 作者:wmmy2008

------------------------------------------------
#纯属个人理解,如有问题敬请谅解!
#kernel version: 2.6.26
#Author: andy wang
-------------------------------------------------
linux内核fs/sysfs目录下面dir.c是建立目录的文件, file.c定义了建立属性文件相关函数,创建二进制文件的函数定义在bin.c .
 
sysfs创建目录文件
 
sysfs建立目录的软件流程sysfs_create_dir()->create_dir()->sysfs_new_dirent()->sysfs_add_one();
sysfs中每个目录都对应一个kobj结构 , 每个文件(包括目录文件)都对应一个sysfs_dirent对象 ,在建立目录和文件后, 内存中会形成一颗以sysfs_root为根的目录树结构.
下面是create_dir()的代码:
610 static int create_dir(struct kobject *kobj, struct sysfs_dirent *parent_sd,
611                       const char *name, struct sysfs_dirent **p_sd)
612 {
613         umode_t mode = S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO;
614         struct sysfs_addrm_cxt acxt;
615         struct sysfs_dirent *sd;
616         int rc;
617            
618         /* allocate */
619         sd = sysfs_new_dirent(name, mode, SYSFS_DIR);
620         if (!sd)
621                 return -ENOMEM;
622         sd->s_dir.kobj = kobj;
623            
624         /* link in */
625         sysfs_addrm_start(&acxt, parent_sd);
626         rc = sysfs_add_one(&acxt, sd);
627         sysfs_addrm_finish(&acxt);
628
629         if (rc == 0)
630                 *p_sd = sd;
631         else
632                 sysfs_put(sd);
633
634         return rc;
635 }
 
613行指定文件的mode为目录文件可读写, 接下来第619sysfs_new_dirent()为文件分配对应的sysfs_dirent对象 ,, sd->s_dir.kobj = kobj找到它的kobj对象,也可以进一步说明这是一个目录文件.
625-627API的目的是将建立的sysfs_dirent对象加到以sysfs_root对象为根的目录树中 ,在以后动态建立文件时会根据名字查找到它
最后就是返回sysfs_dirent对象, kobj->sd指向它.
 好了,这个目录的信息就已经记录在内存中了.
 
sysfs创建属性文件
 
sysfs建立属性文件的流程: sysfs_create_file()->sysfs_add_file()->sysfs_add_file_mode();
下面重点看看sysfs_add_file_mode()函数的实现:
480 int sysfs_add_file_mode(struct sysfs_dirent *dir_sd,
481                         const struct attribute *attr, int type, mode_t amode)
482 {
483         umode_t mode = (amode & S_IALLUGO) | S_IFREG;
484         struct sysfs_addrm_cxt acxt;
485         struct sysfs_dirent *sd;
486         int rc;
487
488         sd = sysfs_new_dirent(attr->name, mode, type);
489         if (!sd)
490                 return -ENOMEM;
491         sd->s_attr.attr = (void *)attr;
492
493         sysfs_addrm_start(&acxt, dir_sd);
494         rc = sysfs_add_one(&acxt, sd);
495         sysfs_addrm_finish(&acxt);
496
497         if (rc)
498                 sysfs_put(sd);
499
500         return rc;
501 }
 
488行函数在cache中创建一个sysfs_dirent对象 ,接下来sd->s_attr.attr = (void *)attr;初始化文件属性
493-495行函数的目的会根据父目录的sysfs_dirent对象把刚才建立的sysfs_dirent加入到目录树中.
 
 
VFS动态创建sysfs文件
 
先看看sysfs目录文件索引节点操作方法的定义
const struct inode_operations sysfs_dir_inode_operations = {
         .lookup                = sysfs_lookup,
         .setattr       = sysfs_setattr,
};
 
在以前的文章中已经介绍过vfs查找文件创建inode的过程 inode->i_op->lookup()
sysfs中目录文件inode定义的这个回调函数是sysfs_lookup()
 
665 static struct dentry * sysfs_lookup(struct inode *dir, struct dentry *dentry,
666                                 struct nameidata *nd)
667 {
668         struct dentry *ret = NULL;
669         struct sysfs_dirent *parent_sd = dentry->d_parent->d_fsdata;
670         struct sysfs_dirent *sd;
671         struct inode *inode;
672
673         mutex_lock(&sysfs_mutex);
674
675         sd = sysfs_find_dirent(parent_sd, dentry->d_name.name);
676
677         /* no such entry */
678         if (!sd) {
679                 ret = ERR_PTR(-ENOENT);
680                 goto out_unlock;
681         }
682
683         /* attach dentry and inode */
684         inode = sysfs_get_inode(sd);
685         if (!inode) {
686                 ret = ERR_PTR(-ENOMEM);
687                 goto out_unlock;
688         }
689
690         /* instantiate and hash dentry */
691         dentry->d_op = &sysfs_dentry_ops;
692         dentry->d_fsdata = sysfs_get(sd);
693         d_instantiate(dentry, inode);
694         d_rehash(dentry);
695
696  out_unlock:
697         mutex_unlock(&sysfs_mutex);
698         return ret;
699 }
 
先看第669,在上篇文章中介绍过sysfs根目录的sysfs_dirent对象初始化给了根目录的dentry. 这个时候就需要取出这个sysfs_dirent对象了
675行代码就是根据文件名字查找出对应的sysfs_dirent对象.
684行函数会在内存中建立文件的索引节点inode, 并由sfs_dirent对象初始化这个indoe, 初始化indoe的函数为sysfs_init_inode() 前面已经分析过了.
692行函数dentry->d_fsdata = sysfs_get(sd); 把这个文件的sysfs_dirent对象初始化给目录项对象dentyr.
693-694,关联文件inodedentry, 并把dentry加入到对应的散列表中.
到这里这个文件的inodedentry就在内存中建立起来了.
 
 
阅读(646) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~