文件系统--procfs中进程目录的问题

procfs是一个特殊的文件系统,和sysfs一样,它是一个只有在你看的时候才会存在的文件系统,它们一样都是用来进行内核-用户态通信的,它们和netlink或者syscall的区别在于它们是文件的方式,大量的文件系统接口都可以使用,免去了编写c代码或者其它代码的工作量,只需要cat,echo等简单命令就可以和内核交互。
若按照常规方式来理解procfs,那么其中的文件在存在之前必然需要先创建,事实上也真的是这样的,create_proc_entry和proc_mkdir都是做这事的,于是猜想那里面的以pid作为目录名的目录也是proc_mkdir之类建立的,然后狠在sys_fork的调用路径中找这类函数,结果枉然!Why?我们忽略了procfs文件系统的实质,对linux的vfs理解不够深刻!所谓的fs仅仅是一个接口,一个数据通信的接口,一个文件就是一个数据源,只要能从中读取数据即可,因此简单说一个实体只要对read起反应那它就是一个文件,vfs只是将这类实体做了一个集合。因此磁盘文件是文件,内存数据也是文件,磁盘作为不易失介质的作用是保存数据,而内存作为易失介质只要在其不复位的情况下能提供数据即可,所以没有必要必须先创建一个文件,只要内核中的数据结构保持完整,当有read请求到来的时候能把数据推出去即可。
因此,看一下proc_root这个proc_dir_entry就可以了,其中的proc_root_operations有readdir这个回调函数proc_root_readdir:
static int proc_root_readdir(struct file * filp, void * dirent, filldir_t filldir)
{
...
if (nr < FIRST_PROCESS_ENTRY) {
int error = proc_readdir(filp, dirent, filldir);
...
filp->f_pos = FIRST_PROCESS_ENTRY;
}
...
ret = proc_pid_readdir(filp, dirent, filldir); //在这个函数中开始遍历当前所有的进程,也就是遍历TGID,一次遍历有限个数,并且取得相应的信息
return ret;
}
并不一定非要先创建所谓的文件才能读取文件的内容,重要的是任何数据结构只要关联一个file_operations并且关联一个挂载点,那么它就可以被作为文件来操作,也就是说,套在linux的vfs框架上的任何数据结构都可以作为文件,这个意义上,磁盘文件只是文件的一种特殊形式罢了。
上述的readdir也是一个回调函数,它读取了file结构体表示的目录(目录也是一个文件)下的所有文件,取得这些文件的信息后填入dirent,linux同时提供了readdir这个系统调用,这个系统调用实现的高效性在于文件系统的文件名和文件内容的分离,文件名仅仅体现在目录的属性或者元数据上,一般文件的元数据中不包含文件名,目录中的文件名指向该文件名对应的文件体,这样readdir只需访问目录的属性就可以取出该目录下的所有文件名称及其简单属性了,这种名称和内容分离的另一个好处是很方便实现符号链接,因为符号链接即是多个文件名对应一个文件,这样只需将不同目录中的多个文件名指向一个文件即可,而无需在文件的元数据中保存一个变长的文件名列表,另外,文件名和文件内容的分开存放对于减少磁盘碎片也是一个帮助,文件的改名或者改内容操作只会集中在某一个区域中。

你可能感兴趣的:(文件系统)