嵌入式技术
本文主要对Linux网络文件系统的注册与挂载过程进行分析
一、简介
Linux中"万物皆文件",socket在Linux中对应的文件系统叫Sockfs,每创建一个socket,就在sockfs中创建了一个特殊的文件,同时创建了sockfs文件系统中的inode,该inode唯一标识当前socket的通信。
本文的重点放在sockfs文件系统的注册和挂载流程上,以后会对socket的底层来龙去脉进行详细地分析与记录。
二、三个核心结构体
1、struct file_system_type
file_system_type结构体代表Linux内核的各种文件系统,每一种文件系统必须要有自己的file_system_type结构,用于描述具体的文件系统的类型,如ext4对应的ext4_fs_type,struct file_system_type结构体如所示:
如struct file_system_type * next结构体成员,所有文件系统的file_system_type结构形成一个链表,在fs/filesystem.c中有一个全局的文件系统变量。
在Linux内核中sock_fs_type结构定义代表了sockfs的网络文件系统,如下所示:
struct mount如下:
三、sockfs文件系统的注册
Linux内核初始化时,执行sock_init()函数登记sockfs,sock_init()函数如下:
注册函数:
注册函数中的find函数如下,for循环一开始的file_systems变量就是上面说的注册文件系统使用到的全局变量指针,strncmp去比较file_system_type的第一项name(文件系统名)是否和将要注册的文件系统名字相同,如果相同返回的P就是指向同名file_system_type结构的指针,如果没找到则指向NULL。
在返回register_filesystem函数后,判断返回值,如果找到重复的则返回EBUSY错误,如果没找到重复的,就把当前要注册的文件系统挂到尾端file_system_type的next指针上,串联进链表,至此一个文件系统模块就注册好了。
四、sockfs文件系统的安装
在上面的sock_init()函数中的sock_mnt = kern_mount(&sock_fs_type)开始进行安装。kern_mount函数主要用于那些没有实体介质的文件系统,该函数主要是获取文件系统的super_block对象与根目录的inode与dentry对象,并将这些对象加入到系统链表。kern_mount宏如下所示:
kern_mount_data如下:
调用:vfs_kern_mount
vfs_kern_mount函数调用mount_fs获取该文件系统的根目录的dentry,同时也获取super_block,具体实现如下:
其中type->mount()继续调用了sockfs的回调函数sockfs_mount
以上函数进行超级块、根root、根dentry相关的创建及初始化操作,其中上面的s->s_d_op =dops就说指向了sockfs_ops结构体,也就是该sockfs文件系统的struct super_block的函数操作集指向了sockfs_ops。
该函数表对sockfs文件系统的节点和目录提供了具体的操作函数,后面涉及到的sockfs文件系统的重要操作均会到该函数表中查找到对应的操作函数,例如Linux内核在创建socket节点时会查找sockfs_ops的alloc_inode函数, 从而调用sock_alloc_indode函数完成socket以及inode节点的创建。
全部0条评论
快来发表一下你的评论吧 !