linux文件系统的系统分析--(九)sysfs下属性文件的读写

11 篇文章 1 订阅

sysfs的属性文件的读写,我们先看下open,open系统调用最终会调用sysfs_open_file

       struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;    //获取sysfs_dirent结构
struct kobject *kobj = attr_sd->s_parent->s_dir.kobj;                //根据sysfs_dirent结构获取上一层结构的kobj对象
struct sysfs_buffer *buffer;
const struct sysfs_ops *ops;

        下面是几步关键步骤:

        1、 if (kobj->ktype && kobj->ktype->sysfs_ops)
ops = kobj->ktype->sysfs_ops;                         //操作方法用的是ktype的sysfs_ops

        2、对文件的读写权限做一些检查

        3、 buffer->needs_read_fill = 1;
        buffer->ops = ops;                                    //buffer的ops指向了前面的ops
        file->private_data = buffer;                     //file的private_data指向了buffer

                这一步的指针操作在后面的read和write中可以看清楚

        read和write是类似的过程,我们仅仅看read

        sysfs_read_file:

        1、struct sysfs_buffer * buffer = file->private_data;  //根据open中的指针操作获取buffer指针

        2、调用fill_read_buffer函数

            struct sysfs_dirent *attr_sd = dentry->d_fsdata;
            struct kobject *kobj = attr_sd->s_parent->s_dir.kobj;
            const struct sysfs_ops * ops = buffer->ops;      //获取了ktype中的sysfs_ops

                    调用ops->show(kobj, attr_sd->s_attr.attr, buffer->page);

        3、调用simple_read_from_buffer将读取到的内容拷贝到用户空间(copy_to_user)


        这里还有一个最后的疑问,这里的ops到底是什么,show和store方法是怎么样的?

        我们以kobject-example.c为例做说明:

        找kobj->ktype->sysfs_ops

        在kobject_create-->kobject_init(kobj, &dynamic_kobj_ktype);

       static struct kobj_type dynamic_kobj_ktype = {
.release  = dynamic_kobj_release,
.sysfs_ops  = &kobj_sysfs_ops,
        };

       const struct sysfs_ops kobj_sysfs_ops = {
.show = kobj_attr_show,
.store  = kobj_attr_store,
       };

[cpp]   view plain  copy
  1. /* default kobject attribute operations */  
  2. static ssize_t kobj_attr_show(struct kobject *kobj, struct attribute *attr,  
  3.                   char *buf)  
  4. {  
  5.     struct kobj_attribute *kattr;  
  6.     ssize_t ret = -EIO;  
  7.   
  8.     kattr = container_of(attr, struct kobj_attribute, attr);  
  9.     if (kattr->show)  
  10.         ret = kattr->show(kobj, kattr, buf);  
  11.     return ret;  
  12. }  

      最后就是调用kattr->show方法,也就是:

[cpp]   view plain  copy
  1. static ssize_t foo_show(struct kobject *kobj, struct kobj_attribute *attr,  
  2.             char *buf)  
  3. {  
  4.     return sprintf(buf, "%d\n", foo);  
  5. }  

     

     而对与ldd3中lddbus的例子,其实也是类似:

     在bus_register函数中:

     priv->subsys.kobj.ktype = &bus_ktype;

[cpp]   view plain  copy
  1. static struct kobj_type bus_ktype = {  
  2.     .sysfs_ops  = &bus_sysfs_ops,  
  3. };  


[cpp]   view plain  copy
  1. static const struct sysfs_ops bus_sysfs_ops = {  
  2.     .show   = bus_attr_show,  
  3.     .store  = bus_attr_store,  
  4. };  


[cpp]   view plain  copy
  1. static ssize_t bus_attr_show(struct kobject *kobj, struct attribute *attr,  
  2.                  char *buf)  
  3. {  
  4.     struct bus_attribute *bus_attr = to_bus_attr(attr);  
  5.     struct bus_type_private *bus_priv = to_bus(kobj);  
  6.     ssize_t ret = 0;  
  7.   
  8.     if (bus_attr->show)  
  9.         ret = bus_attr->show(bus_priv->bus, buf);  
  10.     return ret;  
  11. }  


    最终是调用bus_attr的show方法,就是:

[cpp]   view plain  copy
  1. static ssize_t show_bus_version(struct bus_type *bus, char *buf)  
  2. {  
  3.     return snprintf(buf, PAGE_SIZE, "%s\n", Version);  
  4. }  
  5.   
  6. static BUS_ATTR(version, S_IRUGO, show_bus_version, NULL);  


    根据这个流程走下来,再根据kobject-example.c和lddbus的例子,我们可以很清晰的了解sysfs中属性文件的读写过程。

    sysfs到分析到这里了,我们整体上把握了sysfs的安装挂载,目录文件的创建和读写操作。

    因为sysfs是将设备模型导入到用户空间的内存文件系统,下面我们就要由sysfs来看kobject,也就是Linux的设备模型了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值