mount挂载分析

一、挂载文件系统的命令

mount -t ext4 /dev/sdb1 /mnt/sdb1

把设备节点/dev/sdb1,即插入的硬盘设备,cat /dev/sdb1可以直接访问硬盘的二进制数据,以ext4文件系统格式挂载到/mnt/sdb1目录下。挂载结束后,就可以访问/mnt/sdb1目录的方式访问磁盘空间的数据了。

二、如何挂载

1、mount命令会去执行mount系统调用

fs/namespace.c
SYSCALL_DEFINE5(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);


}

准备好应用层传递下来的参数,详见第一部分描述。而后继续往下执行

do_mount
    path_mount
        do_new_mount
            vfs_kern_mount
                mount_fs

其中mount_fs的源码

struct dentry *
mount_fs(struct file_system_type *type, int flags, const char *name, void *data)
{

        root = type->mount(type, flags, name, data);

此时就需要依赖于struct file_system_type结构体

2、系统初始化的时候,会初始化各种类型的文件系统。以ext4为例,通过

module_init(ext4_init_fs)

初始化注册文件系统

register_filesystem(&ext4_fs_type)

其中ext4_fs_type的定义

static struct file_system_type ext4_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "ext4",
        .mount          = ext4_mount,
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
};
MODULE_ALIAS_FS("ext4");

3、在do_new_mount中,通过get_fs_type函数加上fstype参数,即mount -t type的type值,找到对应的file_system_type结构体

static int do_new_mount(struct path *path, const char *fstype, int flags,
                        int mnt_flags, const char *name, void *data)
{
        type = get_fs_type(fstype);
        if (!type)
                return -ENODEV;

        mnt = vfs_kern_mount(type, flags, name, data);
  

最终mount_fs函数中type->mount对应着ext4_mount函数的具体实现。

ext4_mount
    mount_bdev

mount_bdev的源码

struct dentry *mount_bdev(struct file_system_type *fs_type,
        int flags, const char *dev_name, void *data,
        int (*fill_super)(struct super_block *, void *, int))
{
        struct block_device *bdev;
        struct super_block *s;
                
        bdev = blkdev_get_by_path(dev_name, mode, fs_type);
        if (IS_ERR(bdev))
                return ERR_CAST(bdev);

        s = sget(fs_type, test_bdev_super, set_bdev_super, flags | MS_NOSEC,
                 bdev);

        return dget(s->s_root);

3.1、通过blkdev_get_by_path的参数dev_name,即/dev/sdb1打开设备

3.2、通过sget函数获取打开设备super_block内容。super_block内容是什么?参考:

https://zhuanlan.zhihu.com/p/106459445

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值