sysfs文件系统之建立文件

11 篇文章 1 订阅
------------------------------------------------ 
#纯属个人理解,如有问题敬请谅解!

#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, 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;

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为目录文件可读写, 接下来第619行sysfs_new_dirent()为文件分配对应的sysfs_dirent对象 ,, sd->s_dir.kobj = kobj找到它的kobj对象,也可以进一步说明这是一个目录文件.

第625-627行API的目的是将建立的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,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;

488         sd = sysfs_new_dirent(attr->name, mode, type);

489         if (!sd)

490                 return -ENOMEM;

491         sd->s_attr.attr = (void *)attr;

493         sysfs_addrm_start(&acxt, dir_sd);

494         rc = sysfs_add_one(&acxt, sd);

495         sysfs_addrm_finish(&acxt);

497         if (rc)

498                 sysfs_put(sd);

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, 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;
673         mutex_lock(&sysfs_mutex);

675         sd = sysfs_find_dirent(parent_sd, dentry->d_name.name);

677         /* no such entry */

678         if (!sd) {

679                 ret = ERR_PTR(-ENOENT);

680                 goto out_unlock;

681         }

683         /* attach dentry and inode */

684         inode = sysfs_get_inode(sd);

685         if (!inode) {

686                 ret = ERR_PTR(-ENOMEM);

687                 goto out_unlock;

688         }

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);

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行,关联文件inode和dentry, 并把dentry加入到对应的散列表中.

到这里这个文件的inode和dentry就在内存中建立起来了.

 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值