sysfs与普通文件系统的关系

转:https://blog.csdn.net/chqsy/article/details/81001600

 基础:

VFS inode 包含文件访问权限、属主、组、大小、生成时间、访问时间、最后修改时间等信息。它是Linux 管理文件系统的最基本单位,也是文件系统连接任何子目录、文件的桥梁。

        内核使用inode结构体在内核内部表示一个文件。因此,它与表示一个已经打开的文件描述符的结构体(即file 文件结构)是不同的,我们可以使用多个file 文件结构表示同一个文件的多个文件描述符,但此时,所有的这些file文件结构全部都必须只能指向一个inode结构体

file结构体指示一个已经打开的文件(设备对应于设备文件),其实系统中的每个打开的文件在内核空间都有一个相应的struct file结构体,它由内核在打开文件时创建,并传递给在文件上进行操作的任何函数,直至文件被关闭。如果文件被关闭,内核就会释放相应的数据结构。在内核源码中,struct file要么表示为file,或者为filp(意指“file pointer”), 注意区分一点,file指的是struct file本身,而filp是指向这个结构体的指针


sysfs中的目录和文件与kobject和attribute对应,而普通文件系统是file和inodesysfs在上层也是通过普通的read(),write()等系统调用进行操作的,那么需要将file_operations转换成最终的show()/store()。怎么转?因为属性都是属于kobject的,所以最后的读写肯定与kobject有关,先从kobject找找线索,看前面kobject有个属性——sd,kernfs_node数据结构,是kobject在sysfs的表示。我们从分析这个核心数据结构入手。

kernfs_node

 

count、active,相关的计数,原子的。

parent,本节点的父节点,这个比较重要,属性是文件,父节点才是kobject。

name,节点名字。

rb,红黑树节点。

ns、has,命名空间相关。

dir、symlink、attr,节点的类型,表示该节点是目录、符号链接还是属性。三个属性定义在联合体中,我们在这关注是的attr。

priv,私有数据,看到私有数据应该推测,有用的东西就在这里传递,事实也是如此,在本节描述的访问属性的场景下,kobject就作为私有数据随kernfs_node传递。

flags、mode,与文件的相关属性含义一致。

ino,推测是子设备号。

iattr,节点本身的属性。

那么file如何转换成kernfs_node的呢,类比一下,普通文件有file和inode,这里kernfs_node应该是相当于inode,那还应该有代表文件的结构与之对应,没错,是有这个结构。这个结构是什么,不妨先在kernfs_node中找线索。既然我们的研究对象是属性,那就看看联合里的attr对应的数据结构。

kernfs_elem_attr

 

ops,对于kernfs的操作函数。

open,打开的kernfs_node。

size,没有查到用途,不影响分析。

notify_next,通知kernfs文件,具体功能不详,不影响分析。

只关注ops,目前linux中基本所有的操作都独立抽象出了数据结构,这个数据结构应该是操作kernfs的函数,可能与我们找的答案有关

kernfs_ops

 

atomic_write_len,写是以kernel page为边界的,如果没有设置atomic_write_len,超过PAGE_SIZE的写操作会被分成几个操作进行。如果设置了atomic_write_len,那么超过这个设置值的写操作,atomic_write_len以内的部分是原子写,超过的部分直接返回-E2BIG。

prealloc,设置了用mmap,不设置用read/write。因为read/wirte有自己的buf,与prealloc的buf不兼容。

seq_show、seq_start、seq_next、seq_stop,顺序文件操作。下面会详细分析。这里需要关注他们的参数。

read、write、mmap,读,写,内存映射函数,这里关注他们的参数。

 

看一下seq_xx和read的原型,参数分别为seq_file和kernfs_open_file。从名字上看kernfs_open_file和kernfs_node的关系,很像file和inode的关系。不妨先看看kernfs_open_file。

kernfs_open_file

 

kn,所属的目录节点。

file,代表打开文件。

priv,私有数据结构。

mutex,互斥体。

list,确实没有查到在哪里调用,暂时推测不出用途,不影响分析。

pralloc_buf,mmap使用。

atomic_write_len,同kernfs_elem_attr。

mmaped,是否已经进行了ioremap。

vm_ops,虚拟内存管理操作。

从核心类的成员可能得出这样的推测,kernfs_open_file.file存储普通文件的file指针,在进行读写是用container_of()从file里获得kernfs_open_file结构体。以前的内核可能是这么做的,但是现在不是这样的。这里要提到上面数的另一个核心数据结构seq_file。

seq_file

seq_file是为proc文件系统设计的,来历是这样的,由于procfs的默认操作函数只使用一页的缓存,在处理较大的proc文件时就有点麻烦,并且在输出一系列结构体中的数据时也比较不灵活,需要自己在read_proc函数中实现迭代,容易出现Bug。所以内核黑客们对一些/proc代码做了研究,抽象出共性,最终形成了seq_file(Sequence file:序列文件)接口。 这个接口提供了一套简单的函数来解决以上proc接口编程时存在的问题,使得编程更加容易,降低了Bug出现的机会。

不只是proc,在需要创建一个由一系列数据顺序组合而成的虚拟文件或一个较大的虚拟文件时,推荐使用seq_file接口。这正是符合bin_attribute的场景。看一下seq_file的结构。

 

这个结构的成员与file差不多,基本不用关心,因为他们都是使用op成员定义的方法操作的,一定意义上可以看作私有成员,图中没有这么画。

需要注意的是结构里有个private,这么多回了应该有这个意识了,看见private就有可能跟我们结构挂上关系。事实也是如此。kernfs_open_file的指针是放到seq_file的private中的

从file到attribute

至此只剩seq_file如何与普通的file联系在一起了,那就简单了,跟大部分驱动程序是一样的,seq_file包含在file的private_data中。整合上述关系,可以在下面类图中表示。

 

从file找到sysfs的属性文件,经历了很长的链条,这个其实是多态,由于c语言的特性,linux驱动程序用了很费劲的方式实现了多态。

上边这个可能还是抽象一点,把ops族对象加入跟为直观,忽略一些中间环节。

从操作上,从VFS的fs到sysfs经历了file_operations域,kernfs_ops域和最终的sys_ops域的转换

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值