LINUX SOCKFS文件系统分析一 sockfs文件系统类型的定义及注册

在之前的文章中,我们介绍了VFS、VFS与进程模块之间的代码分析,也分析了devtmpfs文件系统。

本次我们介绍socketfs,说明下socketfs与vfs之间的关联。

在分析VFS以及分析devtmpfs时,其文件系统变量file_system_type->mount接口实现超级块的创建以及根目录相关的

dentry、inode的创建,在root_inode的i_op接口中,实现了文件及目录inode创建的接口(i_op->mkdir实现目录的创建、i_op->create实现文件的创建)。而针对socket而言,其并不需要创建真实的文件,因此,其root_inode的i_op接口中并没有mkdir、create接口,其主要将进程描述符的struct file类型的指针与socket相关的结构体关联。

 

关于sockfs,主要分析如下几个方面的内容:

一、sockfs文件系统类型的定义、注册及挂载

 

二、sockfs相关的结构体

 

三、socket fd创建的过程

 

四、socket相关的系统调用简要介绍

sockfs文件系统类型的定义及注册

针对sockfs,其在sock_init接口中,进行文件系统的注册以及挂载操作,sock_init的接口流程图如下:

通过调用register_filesystem实现文件系统的注册(文件系统的注册之前文章中已经介绍过,可在此处查看)。

其中sockfs文件系统的定义如下,其mount接口为sockfs_mount

static struct file_system_type sock_fs_type = {

.name =                "sockfs",

.mount =        sockfs_mount,

.kill_sb =        kill_anon_super,

};

 

针对sockfs,调用kern_mount进行sockfs的挂载操作,而kern_mount通过调用vfs_kern_mount进行挂载(但没有调用do_add_mount,将该sockfs挂载到具体目录中,因sockfs无需挂载具体目录)。在vfs_kern_mount->mount_fs->type->mount时,即调用sockfs_mount接口,进行超级块、根root、根dentry相关的创建及初始化操作。如下接口定义,其中sockfs_ops为sockfs的超级块变量相关的操作接口,而sockfs_dentry_operations为sockfs的根dentry的操作接口。

 

static struct dentry *sockfs_mount(struct file_system_type *fs_type,

 int flags, const char *dev_name, void *data)

{

return mount_pseudo(fs_type, "socket:", &sockfs_ops,

&sockfs_dentry_operations, SOCKFS_MAGIC);

}

socketfs 超级块的操作接口,主要包括:

  1. inode节点的创建接口sock_alloc_inode;
  2. inode节点的删除接口sock_destroy_inode;
  3. 文件系统的状态获取接口simple_statfs,可获取文件系统的类型、块大小、文件系统名称大小等

 

static const struct super_operations sockfs_ops = {

.alloc_inode        = sock_alloc_inode,

.destroy_inode        = sock_destroy_inode,

.statfs                = simple_statfs,

};

 

struct socket_alloc {

struct socket socket;//struct socket socket变量,用于表示socketfs模块相关的变量,根据该变量可完成对socket链接的建立、数据收发等操作。

struct inode vfs_inode;//inode节点变量

};

  下面稍微说明下alloc_inode接口,在介绍该接口之前引入结构体struct socket_alloc,该结构体中包含了vfs模块的inode和socket模块的socket变量,可以说该变量链接了VFS与SOCKETFS模块。

下面我们分析下sock_alloc_inode函数,该函数也就是创建struct socket_alloc类型的指针变量,并对该变量中的inode与socket变量进行初始化,具体功能为:

1.初始化socket变量的状态、flag、ops、sk、file等成员变量;

2.初始化socket的等待队列成员变量wq

static struct inode *sock_alloc_inode(struct super_block *sb)

{

struct socket_alloc *ei;

struct socket_wq *wq;



ei = kmem_cache_alloc(sock_inode_cachep, GFP_KERNEL);

if (!ei)

return NULL;

wq = kmalloc(sizeof(*wq), GFP_KERNEL);

if (!wq) {

kmem_cache_free(sock_inode_cachep, ei);

return NULL;

}

init_waitqueue_head(&wq->wait);

wq->fasync_list = NULL;

RCU_INIT_POINTER(ei->socket.wq, wq);



ei->socket.state = SS_UNCONNECTED;

ei->socket.flags = 0;

ei->socket.ops = NULL;

ei->socket.sk = NULL;

ei->socket.file = NULL;



return &ei->vfs_inode;

}

而针对dentry的处理操作接口sockfs_dentry_operations,则提供了sockfs_dname接口,该接口用于生成dentry的名称

 

static const struct dentry_operations sockfs_dentry_operations = {

.d_dname  = sockfs_dname,

};

 

本小节主要介绍socketfs文件系统的注册,并介绍了socketfs的inode节点的创建等内容,介于我们之前已分析了文件系统注册的接口,因此针对socketfs文件系统的注册分析,相对来说简单了许多。

发布了140 篇原创文章 · 获赞 30 · 访问量 45万+

猜你喜欢

转载自blog.csdn.net/lickylin/article/details/102540200
今日推荐