LINUX SYSFS文件系统分析之二 sysfs文件系统相关的结构体说明

上一篇文章简要介绍了sysfs文件系统的注册以及挂载流程,本小节主要介绍sysfs相关的结构体,以便我们可以更深入的理解sysfs。

 

 

  1. 相关结构体说明

我们介绍sysfs相关的结构体,主要是想从结构体之间的联系,建立对sysfs文件系统实现框架的感性认识,以便我们更好的理解sysfs文件系统。

 

 

在我们对单个结构体进行分析之前,我们先来看下这些结构体的关系,如下所示主要包

括kset、kobject、kref、sysf_dirent、kobj_type、sys_ops、sysfs_elem_dir

、sysfs_elem_symlinks、sysfs_elem_attr、sysfs_elem_bin_attr结构体。主要包括sysfs与设备模型关联的结构体、sysfs文件系统目录及文件建立相关、sysfs文件操作相关的结构体等几大部分。

 

 如上图所示,一个kset结构体变量包括一类kobject的集合,而针对一个kset而言,且也是一个目录,因此其也有相应的kobject,而关于kset的引用计数,直接使用kobject->kref实现引用计数的功能。而针对一个kobject而言,其也有相应的方法,即kobj_type,该方法中包括kobject的释放以及show/store接口,还包括默认的属性参数等

 

 

下面我们按上面的分类分别介绍这几类结构体的定义与关联。

 

sysfs与设备模型关联的结构体

与设备模型相关的结构体主要为kset、kobject、kref、sysfs_dirent等,其中kobject表示内核对象,定义了内核对象后,则针对每一个设备类型、驱动类型、总线类型等,均可用一个内核对象表示,在sysfs中一个kobject即代表一个目录,针对sysfs的文件,是没有对应的kobject,kobject仅表示目录。而在设备模型中,针对设备、驱动以及总线而言,均会有对应的内核对象,而针对总线而言,其还会包含kset变量,并通过该kset变量的list成员变量,链接bus下所有具体已注册总线的内核对象(kobject)。通过这几个变量,就实现了与设备驱动模型的关联。

这些结构体的关联如下:

 

 

struct kobject定义说明

下面我们看下kobject的定义,主要包括对象命令、引用计数、对应的sysfs_dirent指针、该kobject所属的kset等。

struct kobject {

const char                *name;//本kobject的名称

struct list_head        entry;//同属于一个kset的kobject子项的链表

struct kobject                *parent;//该kobject对应的父对象

struct kset                *kset;//该kobject所属的kset

struct kobj_type        *ktype;//包括该对象的释放接口、属性操作接口、默认属性等

struct sysfs_dirent        *sd;//该kobject对应的sysfs_dirent指针

struct kref                kref;//该kobject的引用计数

unsigned int state_initialized:1;

unsigned int state_in_sysfs:1;

unsigned int state_add_uevent_sent:1;

unsigned int state_remove_uevent_sent:1;

unsigned int uevent_suppress:1;

};

 

struct kset定义说明

主要包括属于该kset的kobject的链表头、该kset对应的内核对象、kset对应的事件处理接口等

struct kset {

struct list_head list;

spinlock_t list_lock;

struct kobject kobj;

const struct kset_uevent_ops *uevent_ops;

};

struct kref定义

该结构体就是一个原子变量,用于kobject的引用计数。

struct kref {

atomic_t refcount;

};

struct kobj_type定义

该结构体主要是kobject对应的释放接口以及属性操作接口(属性操作接口,主要用于该对象下文件的读写操作)

struct kobj_type{

void (*release)//kobj的释放接口

struct sysfs_ops *sysfs_ops

attribute **default_attrs

...

};

 

struct sysfs_ops定义

struct sysfs_ops {

ssize_t        (*show)(struct kobject *, struct attribute *,char *);

ssize_t        (*store)(struct kobject *,struct attribute *,const char *, size_t);

const void *(*namespace)(struct kobject *, const struct attribute *);

};

 

该结构体主要包括show、store、namespace三个接口指针,其中show、store主要用于属性对应文件的读与写接口,这两个接口需要输入的参数包括kobject、attribute结构体对应的变量。

struct attribute结构体说明

      针对上述的结构体变量attribute,系统中各子模块可通过创建包含该结构体变量attribute的私有变量,从而实现针对具体属性的show/store接口的调用。

我们以struct bus_attribute 结构体变量为例进行简要说明。针对bus目录而言,在进行总线的注

册时,其kobject对象的struct kobj_type变量定义为bus_ktype,其中定义了bus目录对应的show/store接口为bus_attr_show/bus_attr_store,而bus对应的属性结构体为bus_attribute,包含了struct attribute成员变量、show/store接口指针(这个show/store接口即为具体文件的处理接口),当在bus目录下创建文件时,则会创建bus_attribute结构体的变量,而在bus_attr_show/bus_attr_store接口中会根据传入的attribute结构体变量,从而获取bus_attribute结构体类型的变量,然后就调用bus_attribute结构体类型变量的show/store接口,从而实现对具体文件的show/store操作。

struct bus_attribute {

struct attribute        attr;

ssize_t (*show)(struct bus_type *bus, char *buf);

ssize_t (*store)(struct bus_type *bus, const char *buf, size_t count);

};

static const struct sysfs_ops bus_sysfs_ops = {

.show        = bus_attr_show,

.store        = bus_attr_store,

};



static struct kobj_type bus_ktype = {

.sysfs_ops        = &bus_sysfs_ops,

};

 

sysfs文件系统目录及文件建立相关

    sysfs也是内存文件系统,而且sysfs文件系统不允许通过应用层创建文件及目录,而且sysfs文件系统也不再以inode、dentry接口来创建文件及目录,其通过结构体sysfs_dirent进行文件及目录的创建以及关联(该结构体通过红黑色进行关联)。

该结构体的定义如下,主要包括文件或目录的类型(目录、链接、属性文件、bin文件)、红黑树节点、所属的父目录等。

struct sysfs_dirent {

atomic_t                s_count;//引用计数

atomic_t                s_active;

#ifdef CONFIG_DEBUG_LOCK_ALLOC

struct lockdep_map        dep_map;

#endif

struct sysfs_dirent        *s_parent;//该文件或者目录的父目录

const char                *s_name;//名称



struct rb_node                s_rb;//对应的红黑树节点



union {

struct completion        *completion;

struct sysfs_dirent        *removed_list;

} u;



const void                *s_ns; /* namespace tag */

unsigned int                s_hash; /* ns + name hash */

/*标识该目录或文件的类型,目录、链接、属性文件、bin文件等*/

union {

struct sysfs_elem_dir                s_dir;

struct sysfs_elem_symlink        s_symlink;

struct sysfs_elem_attr                s_attr;

struct sysfs_elem_bin_attr        s_bin_attr;

};



unsigned short                s_flags;

umode_t                 s_mode;//该目录或文件的权限

unsigned int                s_ino;

struct sysfs_inode_attrs *s_iattr;

};

struct sysfs_elem_dir        

该结构体表示目录,主要包括内核对象、子目录属性、该目录的红黑树子节点灯

struct sysfs_elem_dir {

struct kobject                *kobj;



unsigned long                subdirs;

/* children rbtree starts here and goes through sd->s_rb */

struct rb_root                children;

};

struct sysfs_elem_symlink

该结构体表示一个链接,针对链接目录或文件,则主要是该链接对应的目标sysfs_dirent变量

struct sysfs_elem_symlink {

struct sysfs_dirent        *target_sd;

};

struct sysfs_elem_attr

该结构体表示一个属性文件,其中包括attribute结构体变量(该结构体主要用于获取该属性文件对应的操作接口,在上面的“struct attribute结构体说明”中已经分析过),而结构体变量sysfs_open_dirent主要是建立属性文件和打开该文件的所有文件描述符的关联。

struct sysfs_elem_attr {

struct attribute        *attr;

struct sysfs_open_dirent *open;

};

sysfs文件操作相关的结构体

在上面介绍struct sysfs_elem_attr时,已经提到了sysfs_open_dirent结构体,下面我们详细说明属性文件相关的结构体,主要包括sysfs_elem_attr、sysfs_open_dirent、sysfs_buffer等,这些结构体之间的关联如下所示,其中sysfs_open_dirent主要是建立属性文件和打开该文件的所有文件描述符的关联,如下所示sysfs_open_dirent中的链表成员buffers链接了所有已打开该文件的sysfs_buffer变量(该变量中包括了文件读写的偏移量、读取时是否需要重新刷新变量值、发生事件计数等信息),而每一个sysfs_buffer结构体变量作为文件描述符的私有指针成员变量,完成与文件描述符的关联。

struct sysfs_open_dirent {

atomic_t                refcnt;//引用计数

atomic_t                event;//事件计数

wait_queue_head_t        poll;//poll机制对应的等待队列头,用于实现属性文件的poll机制,以便进行属性文件相关的事件触发。

struct list_head        buffers; /*链接所有的 sysfs_buffer变量*/

};

struct sysfs_buffer {

size_t                        count;//数据内容长度

loff_t                        pos;//当前的偏移量

char                        * page;//存放读写相关的内容

const struct sysfs_ops        * ops;//show/store接口,在属性文件的open接口sysfs_open_file中会对该变量进行赋值

struct mutex                mutex;

int                        needs_read_fill;//指示是否需要更新该buff中page中的内容

int                        event;//已发生的事件计数

struct list_head        list;

};

 

 

 

以上主要介绍了kset、kobject、kref、sysfs_dirent、sysfs_buffer、sysfs_elem_attr、sysfs_ops、attribute等变量,包含了与设备模型、文件描述符、sysfs文件及目录的创建及访问等内容。下一篇文件介绍sysfs相关的目录与文件创建流程。

发布了140 篇原创文章 · 获赞 30 · 访问量 45万+

猜你喜欢

转载自blog.csdn.net/lickylin/article/details/102594955