接下來,我們進入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()。