Linux那些事儿之我是Sysfs(6)文件系统

来源:互联网 发布:jenkins构建java项目 编辑:程序博客网 时间:2024/05/16 17:42

接下来,我们进入sysfs部分。看看
kobject_add()->create_dir()->sysfs_create_dir()
bus create file->sysfs create file()
. . .
这些sysfs函数的内幕。
说白了,sysfs就是利用VFS的接口去读写kobject的层次结构,建立起来的文件系统。关于sysfs的内容就在fs/sysfs/下。 kobject的层次结构的更新与删除就是那些乱七八糟的XX_register()们干的事情。

在kobject_add()里面,调用了sysfs_create_dir()。让我们看看它究竟是如何create的。

    135 int sysfs_create_dir(struct kobject * kobj)
    136 {
    137         struct dentry * dentry = NULL;
    138         struct dentry * parent;
    139         int error = 0;
    140
    141         BUG_ON(!kobj);
    142
    143         if (kobj->parent)
    144                 parent = kobj->parent->dentry;
    145         else if (sysfs_mount && sysfs_mount->mnt_sb)
    146                 parent = sysfs_mount->mnt_sb->s_root;
    147         else
    148                 return -EFAULT;
    149
    150         error = create_dir(kobj,parent,kobject_name(kobj),&dentry);
    151         if (!error)
    152                 kobj->dentry = dentry;
    153         return error;
    154 }

当你看见这么些新东西,如dentry出现的时候,你一定感到很困惑。诚然,我一度为代码中突然出现的事物感到恐慌,人类对未知的恐惧是与生俱来的,面对死亡,面对怪力乱神,我们抱着一颗敬畏的心灵就可以了。而面对linux,我们始终坚信,未知肯定是可以被探索出来的。妖是妖他妈生的,代码是人他妈写出来的,既然写得出来,那就肯定看得懂。对不起,扯远了....我还是介绍介绍文件系统的基本知识先。

文件系统

文件系统是个很模糊广泛的概念,"文件"狭义地说,是指磁盘文件,广义理解,可以是有组织有次序地存储与任何介质(包括内存)的一组信息。linux把所有的资源都看成是文件,让用户通过一个统一的文件系统操作界面,也就是同一组系统调用,对属于不同文件系统的文件进行操作。这样,就可以对用户程序隐藏各种不同文件系统的实现细节,为用户程序提供了一个统一的,抽象的,虚拟的文件系统界面,这就是所谓"VFS(Virtual Filesystem Switch)"。这个抽象出来的接口就是一组函数操作。

我们要实现一种文件系统就是要实现VFS所定义的一系列接口,file_operations, dentry_operations, inode_operations等,供上层调用。file_operations是对每个具体文件的读写操作,dentry_operations, inode_operations则是对文件的属性,如改名字,建立或删除的操作。

struct file_operations {
ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
int (*open) (struct inode *, struct file *);
...
};
struct dentry_operations {
...
};
struct inode_operations {
int (*create) (struct inode *,struct dentry *,int, struct nameidata *);
struct dentry * (*lookup) (struct inode *,struct dentry *, struct nameidata *);
int (*link) (struct dentry *,struct inode *,struct dentry *);
int (*mkdir) (struct inode *,struct dentry *,int);
int (*rmdir) (struct inode *,struct dentry *);
...}

举个例子,我们写C程序,open(“hello.c”, O_RDONLY),它通过系统调用的流程是这样的

open() ->       /*用户空间*/
-> 系统调用->
sys_open() -> filp_open()-> dentry_open() ->  file_operations->open()           /*内核空间*/

不同的文件系统,调用不同的file_operations->open(),在sysfs下就是sysfs_open_file()。