簡單記錄一下Linux 4.19-rc8從mount system call到呼叫file_system_type.mount()的call flow
SYSCALL_DEFINE5(mount) |--> ksys_mount() |--> do_mount() |--> do_new_mount() |--> type = get_fs_type() |--> vfs_kern_mount(type) |--> mount_fs(type) |--> type->mount()
SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name, char __user *, type, unsigned long, flags, void __user *, data) { return ksys_mount(dev_name, dir_name, type, flags, data); } int ksys_mount(char __user *dev_name, char __user *dir_name, char __user *type, unsigned long flags, void __user *data) { int ret; char *kernel_type; char *kernel_dev; void *options; kernel_type = copy_mount_string(type); ... kernel_dev = copy_mount_string(dev_name); ... options = copy_mount_options(data); ... ret = do_mount(kernel_dev, dir_name, kernel_type, flags, options); ... return ret; } long do_mount(const char *dev_name, const char __user *dir_name, const char *type_page, unsigned long flags, void *data_page) { struct path path; unsigned int mnt_flags = 0, sb_flags; int retval = 0; retval = user_path(dir_name, &path); if (flags & MS_REMOUNT) retval = do_remount(&path, flags, sb_flags, mnt_flags, data_page); else if (flags & MS_BIND) retval = do_loopback(&path, dev_name, flags & MS_REC); else if (flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE)) retval = do_change_type(&path, flags); else if (flags & MS_MOVE) retval = do_move_mount(&path, dev_name); else retval = do_new_mount(&path, type_page, sb_flags, mnt_flags, dev_name, data_page); ... return retval; } static int do_new_mount(struct path *path, const char *fstype, int sb_flags, int mnt_flags, const char *name, void *data) { struct file_system_type *type; struct vfsmount *mnt; int err; type = get_fs_type(fstype); ... mnt = vfs_kern_mount(type, sb_flags, name, data); ... put_filesystem(type); ... err = do_add_mount(real_mount(mnt), path, mnt_flags); ... return err; } struct vfsmount * vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void *data) { struct mount *mnt; mnt = alloc_vfsmnt(name); ... root = mount_fs(type, flags, name, data); ... return &mnt->mnt; } struct dentry * mount_fs(struct file_system_type *type, int flags, const char *name, void *data) { struct dentry *root; ... root = type->mount(type, flags, name, data) ... return root; }
-
參考資料:
- https://lkml.org/lkml/2018/3/16/905, fs: add ksys_mount() helper; remove in-kernel calls to sys_mount()
- https://www.halolinux.us/kernel-architecture/the-mount-system-call.html, The Mount System Call