linux网络协议栈分析——网络文件系统初始化

来源:互联网 发布:unity3d怎么注册 编辑:程序博客网 时间:2024/05/16 14:38

由于涉及到网络,和文件系统的读写数据接口比较起来,使用网络收发数据的接口最抽象的概念就是socket。网络收发数据的接口是BSD定义的一套接口,文件系统是open与close的对应。

首先需要了解的是网络文件系统的初始化:

static int __init sock_init(void)
{
 /*
  *      Initialize sock SLAB cache.
  */

 sk_init();

 /*
  *      Initialize skbuff SLAB cache
  */
 skb_init();

 /*
  *        */

 init_inodecache();
 register_filesystem(&sock_fs_type);
 sock_mnt = kern_mount(&sock_fs_type);

 /* The real protocol initialization is performed in later initcalls.
  */

#ifdef CONFIG_NETFILTER
 netfilter_init();
#endif

 return 0;
}

core_initcall(sock_init); /* early initcall */

core_initcall可以查阅相关资料,流程就是机器在启动初始化时调用了sock_init函数。

网络文件系统是特殊的,文件系统的挂载没有安装常规文件系统的做法来实现:
1、首先没有查找全局文件系统链表获得文件系统类型
2、网络文件系统类型并没有真正挂载到VFS的目录树中,而是通过全局变量来使用。即:

static struct vfsmount *sock_mnt __read_mostly;//保存为全局变量,需要时直接使用
sock_mnt = kern_mount(&sock_fs_type);

也就是说这个文件系统是无法通过常规的文件系统接口来使用的,更无法通过cd、ls等命令来查看了。

那么文件系统的注册还需要吗?就网络文件系统本身的功能来说是不需要的,但是需要保证不能有其他进程再重复的挂载网络文件系统。

register_filesystem(&sock_fs_type);

文件系统的注册保证网络文件系统已经增加到全局文件系统链表中。

文件系统挂载过程可以查看相关源代码。重点说明代表网络文件系统类型的sock_fs_type结构:

static struct file_system_type sock_fs_type = {
 .name =  "sockfs",
 .get_sb = sockfs_get_sb,
 .kill_sb = kill_anon_super,
};
继续:

static int sockfs_get_sb(struct file_system_type *fs_type,
    int flags, const char *dev_name, void *data,
    struct vfsmount *mnt)
{
 return get_sb_pseudo(fs_type, "socket:", &sockfs_ops, SOCKFS_MAGIC,mnt);
}

在得到文件系统超级块的过程中,get_sb_pseudo通过

s->s_op = ops ? ops : &simple_super_operations;
把sockfs_ops赋值给s->s_op。

继续:

static const struct super_operations sockfs_ops = {
 .alloc_inode = sock_alloc_inode,
 .destroy_inode =sock_destroy_inode,
 .statfs = simple_statfs,
};

继续:

static struct inode *sock_alloc_inode(struct super_block *sb)
{
 struct socket_alloc *ei;

 ei = kmem_cache_alloc(sock_inode_cachep, GFP_KERNEL);
 if (!ei)
  return NULL;
 init_waitqueue_head(&ei->socket.wait);

 ei->socket.fasync_list = NULL;
 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;
}

总结起来是三个全局变量了:sock_mntsock_fs_type,sockfs_ops。

sock_inode_cachep是sock_init中的 init_inodecache()声明的全局变量:

static struct kmem_cache *sock_inode_cachep __read_mostly;

 


 

原创粉丝点击