linux内核sys_mount()分析

本文详细分析了Linux内核的sys_mount()函数,探讨了从用户态参数拷贝到内核态的原因,以及挂载过程中涉及的关键步骤,包括kern_path()寻找目录项结构、do_mount()的后续操作、do_kern_mount()的超级块加载和vfsmount结构初始化,最后通过do_add_mount()构建挂载树。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 概述

        今天本来打算写一篇关于linux内核sys_mount()代码分析的文章,习惯性地打开google,看看是否有别人写的比较好,可以参考参考,打开第一篇发现居然是自己以前写的博客,真是囧,而且也记录在优快云上,本想直接行使拿来主义,但看了下内容,发觉略有不妥,于是在那篇博客的基础上进行些修改和润色。
        Linux下任何块设备在使用之前,首先要对其进行格式化成特定文件系统,如mkfs.ext3等,然后再将其挂载到系统中特定目录下,于是通过该挂载点即可访问该块设备文件系统下的所有文件和目录等。如   mount -t ext3 -o option /device/hda  /home/mountdir 便将设备/dev/hda挂载到了/home/mountdir下,我们今天的重点就是钻研kernel在该命令下到底做了些什么。参考的内核版本是linux2.6.36,本人博客如无作特别说明,内核的版本都是2.6.36。

2. 实现

2.1 相关数据结构

       相关数据结构留到我们代码分析完成以后再写。

2.2 sys_mount()流程分析

      内核mount函数的入口为sys_mount(),你需要在fs/namespace.c的SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name, char __user *, type, unsigned long, flags, void __user *, data)才能找到其实现,其源代码如下:
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_dir;
	char *kernel_dev;
	unsigned long data_page;

	/* 以下几个函数将用户态参数拷贝至内核态,包括:
	** 1. kernel_type:挂载文件系统类型,如ext3
	** 2. kernel_dir:   挂载点路径
	** 3. dev_name:  设备名称
	** 4. data_pages: 选项信息
	*/
	ret = copy_mount_string(type, &kernel_type);
	if (ret < 0)
		goto out_type;

	kernel_dir = getname(dir_name);
	if (IS_ERR(kernel_dir)) {
		ret = PTR_ERR(kernel_dir);
		goto out_dir;
	}

	ret = copy_mount_string(dev_name, &kernel_dev);
	if (ret < 0)
		goto out_dev;

	ret = copy_mount_options(data, &data_page);
	if (ret < 0)
		goto out_data;
	
	/*  调用do_mount 完成主要挂载工作 */
	ret = do_mount(kernel_dev, kernel_dir, kernel_type, flags,
		(void *) data_page);

	free_page(data_page);
out_data:
	kfree(kern
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值