结合exofs的挂载分析mount系统调用。
比如执行命令:mount -t exofs -o pid=65536 /dev/osd0 /mnt/exofs/ 对exofs进行挂载。
mount系统调用的原型为:
#include
int mount(const char *source, const char *target,
const char *filesystemtype, unsigned long mountflags,
const void *data);
实际调用为:mount("/dev/osd0", "/mnt/exofs/", "exofs", MS_MGC_VAL, "pid=65536"),其中参数MS_MGC_VAL仅仅是为了兼容以前的老版本,没什么实际意义。类型为exofs,也就是在/proc/filesystems文件中列出的。
接下来就会传到内核里面来,内核里的mount系统调用(3.3内核)原型如下:
./fs/namespace.c
SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name,
char __user *, type, unsigned long, flags, void __user *, data)
接下来调用:
do_mount(“/dev/osd0”, “/mnt/exofs”, “exofs”, MS_MGC_VAL, "pid=65536");
函数原型如下:
long do_mount(char *dev_name, char *dir_name, char *type_page,
unsigned long flags, void *data_page)
这里由于flags为MS_MGC_VAL,所以函数do_mount()最终调用do_new_mount()函数,原型如下:
static int do_new_mount(struct path *path, char *type, int flags,
int mnt_flags, char *name, void *data)
这里mnt_flags为0,name为设备名。
该函数首先调用do_kern_mount()获取虚拟文件系统挂载信息结构体struct vfsmount。该函数原型如下:
static struct vfsmount *
do_kern_mount(const char *fstype, int flags, const char *name, void *data)
该函数具体步骤如下:
1. 首先调用get_fs_type()由文件系统类型字符串获取该文件系统对应的文件系统描述符结构体struct file_system_type(这里一般是在文件系统模块插入调用register_filesystem()进行注册的)。
2. 调用vfs_kern_mount()进行实际的挂载操作,获取安装点(创建文件系统实例结构体struct vfsmount)。(实际是通过调用mount_fs()获取文件系统的根目录项,然后根据该根目录项初始化一个文件系统实例结构体struct vfsmount,并将其返回)
3. 如果上述过程没有出错,并且文件系统类型标志type->fs_flags的FS_HAS_SUBTYPE置位,并且加载时超级块为空,则调用获取子类型的超级块。
4. 调用put_filesystem()释放文件系统描述符。
函数mount_fs()的核心是调用之前特定文件系统(这里是exofs)自定义的挂载函数获取对应的根目录项。
exofs对应的挂载函数实现为exofs_mount()
¥29.8
¥9.9
¥59.8