概述
在Linux的世界里,万物皆文件,并且都是通过虚拟文件系统VFS来同一管理调用不同的文件系统,因此Linux中可以通过文件IO系统调用来进行操作。而管道就是一个伪文件系统,其通过pipefs来实现。同其他真正的文件系统(ext3、ext4等)一样,都实现VFS中的四种主要对象:super_block、inode、dentry和文件对象file。当对管道进行读写操作时,VFS就会将请求转发给pipefs,而pipefs则会调用自己特定的一些操作函数。
file_system_type操作表
pipefs是一个文件系统,就会有一个被称为file_system_type的数据结构,在系统启动或者文件系统模块挂载时用于在VFS中进行注册。所有的已注册的文件系统的file_system_type结构形成一个链表,链表头由file_systems变量指定。pipefs的file_system_type操作表如下:
static struct file_system_type pipe_fs_type = {
.name = "pipefs",
.mount = pipefs_mount,
.kill_sb = kill_anon_super, //用于移除特殊文件系统的超级块
};
3.18内核版本file_system_type结构体中增加了一个mount成员的钩子函数,
struct dentry *(*mount) (struct file_system_type *, int, const char *, void *);
对于pipefs、sockfs和bdev等伪文件系统调用的该钩子函数实现都是对mount_pseudo函数的封装,该函数主要是根据file_system_type创建一个super_block,并进行一系列的初始化工作,然后根据该超级块和伪文件系统名(pipefs、sockfs和bdev)在内存中分配一个目录项缓存,将其设置为该超级块的根目录的目录项对象,最后返回目录项:
/*
* pipefs should _never_ be mounted by userland - too much of security hassle,
* no real gain from having the whole whorehouse mounted. So we don't need
* any operations on the root directory. However, we need a non-trivial
* d_name - pipe: will go nicely and kill the special-casing in procfs.
*/
static struct dentry *pipefs_mount(struct file_system_type *fs_type,
int flags, const char *dev_name, void *data)
{
return mount_pseudo