mount过程分析之四(vfs_kern_mount->mount_fs->xfs_fs_mount)
2014-10-14 18:01
531 查看
sys_mount - > do_mount -> do_new_mount -> vfs_kern_mount
vfs_kern_mount的作用就是准备好一个完整的mount结构。vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void *data) { struct mount *mnt; struct dentry *root; if (!type) return ERR_PTR(-ENODEV); // alloc一个新的struct mount结构,并初始化里面一部分(如链表指针、mnt_devname等成员内容) mnt = alloc_vfsmnt(name); if (!mnt) return ERR_PTR(-ENOMEM); if (flags & MS_KERNMOUNT) mnt->mnt.mnt_flags = MNT_INTERNAL; // 调用具体文件系统的mount回调函数type->mount,继续挂载操作 root = mount_fs(type, flags, name, data); if (IS_ERR(root)) { mnt_free_id(mnt); free_vfsmnt(mnt); return ERR_CAST(root); } // 完成mnt结构的最后赋值,并返回vfsmount结构 mnt->mnt.mnt_root = root; mnt->mnt.mnt_sb = root->d_sb; mnt->mnt_mountpoint = mnt->mnt.mnt_root; mnt->mnt_parent = mnt; lock_mount_hash(); list_add_tail(&mnt->mnt_instance, &root->d_sb->s_mounts); unlock_mount_hash(); return &mnt->mnt; }
vfs_kern_mount主要完成三件事:
1. alloc_vfsmnt创造一个新的struct mount结构
2. 在mount_fs函数里调用特定文件系统的mount回调函数构造一个root dentry,包含特定文件系统的super block信息
3. 用第二步得到的结果完成对struct mount的构造,返回vfsmnt结构。
那么可以看出mount_fs函数就是下一个要叙述的函数了。
sys_mount - > do_mount -> do_new_mount -> vfs_kern_mount -> mount_fs
这个函数看似复杂,其实主要就做一件事,调用type->mount回调函数。我们前面说过这个回调函数是在每个文件系统类型注册到内核中时实现的一个mount函数,它的前身是get_sb()函数,都是为了完成针对特定文件系统特点的操作而个别实现的回调函数。除了type->mount之外,还有很多安全检查地方,这里就先不多说了。来看一下mount_fs函数:
struct dentry * mount_fs(struct file_system_type *type, int flags, const char *name, void *data) { struct dentry *root; struct super_block *sb; char *secdata = NULL; int error = -ENOMEM; if (data && !(type->fs_flags & FS_BINARY_MOUNTDATA)) { secdata = alloc_secdata(); if (!secdata) goto out; error = security_sb_copy_data(data, secdata); if (error) goto out_free_secdata; } // 这里就是调用file_system_type的mount回调函数的地方,每个文件系统都有自己实现的mount回调函数 root = type->mount(type, flags, name, data); if (IS_ERR(root)) { error = PTR_ERR(root); goto out_free_secdata; } sb = root->d_sb; BUG_ON(!sb); WARN_ON(!sb->s_bdi); WARN_ON(sb->s_bdi == &default_backing_dev_info); sb->s_flags |= MS_BORN; error = security_sb_kern_mount(sb, flags, secdata); if (error) goto out_sb; /* * filesystems should never set s_maxbytes larger than MAX_LFS_FILESIZE * but s_maxbytes was an unsigned long long for many releases. Throw * this warning for a little while to try and catch filesystems that * violate this rule. */ WARN((sb->s_maxbytes < 0), "%s set sb->s_maxbytes to " "negative value (%lld)\n", type->name, sb->s_maxbytes); up_write(&sb->s_umount); free_secdata(secdata); return root; out_sb: dput(root); deactivate_locked_super(sb); out_free_secdata: free_secdata(secdata); out: return ERR_PTR(error); }
mount再往下就是每个文件系统自己实现的mount回调函数了,我们以xfs为例说明。在fs/xfs目录下可以找到xfs文件系统的实现代码。xfs_super.c中可以找到init_xfs_fs模块初始化函数,里面调用了我们最开始提到的register_filesystem(&xfs_fs_type)函数,参数xfs_fs_type就是xfs实现的file_system_type结构。我们已经讲述了xfs_fs_type的定义(http://blog.csdn.net/zr_lang/article/details/39963253),现在我们要着重说一下xfs_fs_mount()函数。
sys_mount - > do_mount -> do_new_mount -> vfs_kern_mount -> mount_fs -> xfs_fs_mount
xfs_fs_mount是xfs自己实现mount回调函数,其实现就是调用mount_bdev()函数,如下:STATIC struct dentry * xfs_fs_mount( struct file_system_type *fs_type, int flags, const char *dev_name, void *data) { return mount_bdev(fs_type, flags, dev_name, data, xfs_fs_fill_super); }
但是这里有一个需要注意的地方就是mount_bdev虽然是一个通用函数,但是其最后一个参数是一个函数指针,xfs传入xfs_fs_fill_super作为参数。xfs_fs_fill_super是xfs实现的一个只适用于xfs的函数,也就是这里还是需要一个每个文件系统各异的处理函数。下面将分别对mount_bdev和xfs_fs_fill_super两个函数进行分析。
http://blog.csdn.net/zr_lang/article/details/40325241 (mount 七)
http://blog.csdn.net/zr_lang/article/details/40343899 (mount 六)
http://blog.csdn.net/zr_lang/article/details/40115013 (mount 五)
http://blog.csdn.net/zr_lang/article/details/40080979 (mount 四)
http://blog.csdn.net/zr_lang/article/details/40049305 (mount 三)
http://blog.csdn.net/zr_lang/article/details/40002285 (mount 二)
http://blog.csdn.net/zr_lang/article/details/39963253 (mount 一)
相关文章推荐
- mount过程分析之五(mount_bdev->fill_super)
- 2012-Linux->17 Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(31,2)
- mount过程分析之三(do_mount -> do_new_mount)
- <四>--RIL层代码分析--整个电话来访过程
- &lt;&lt;深入理解计算机系统&gt;&gt;家庭作业3.38, 分析全过程
- Ubuntu -> VFS:Unable to mount root fs on Unknown-block(0,0)
- <深入浅出>函数调用过程堆栈变化分析
- 分析系统调用的处理过程(systemcall->iret)
- Android系统移植与调试之------->build.prop生成过程分析
- JVM学习笔记二 :垃圾收集的过程分析Eden->Survivor->Tenured
- 安装LFS6.3 VFS:Cannot open root device "sda" 或VFS:Unable to mount root fs on unknown-block(0,0)
- 分析驱动程序在IRQL>=DISPATCH_LEVEL时和DPC过程中不能用KeWaitForSingleObject等待对象的原因
- MMU段式映射(VA -> PA)过程分析
- USB枚举过程的详细分析&lt;转&gt;
- ORiEN v2.11 - 2.12 -> Fisun Alexander 壳分析
- 递归算法详细分析-> C
- Linux启动过程详解1>
- Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(31,2)
- 递归算法详细分析-> C
- vivi分析-head.S->main.c (转)