Linux内核源代码情景分析-文件系统的安装

    执行sudo mount -t ext2 /dev/sdb1 /mnt/sdb,将文件系统挂在到/mnt/sdb上。系统调用mount,映射到内核层执行的是sys_mount。假设/dev/sdb1和/mnt/sdb都位于ext2文件系统中。

asmlinkage long sys_mount(char * dev_name, char * dir_name, char * type,
			  unsigned long flags, void * data)//dev_name指向了"/dev/sdb1",dir_name指向了"/mnt/sdb",type是表示文件系统类型(即格式)的字符串,如"ext2"、"iso9660",flags为安装模式,见下面
{
	int retval;
	unsigned long data_page;
	unsigned long type_page;
	unsigned long dev_page;
	char *dir_page;

	retval = copy_mount_options (type, &type_page);//将参数从用户空间复制到系统空间。这些参数值的长度均以一个页面为限,并且返回页面的起始地址
	if (retval < 0)
		return retval;

	dir_page = getname(dir_name);//将参数从用户空间复制到系统空间,并返回指向该字符串的指针
	retval = PTR_ERR(dir_page);
	if (IS_ERR(dir_page))
		goto out1;

	retval = copy_mount_options (dev_name, &dev_page);//将参数从用户空间复制到系统空间。这些参数值的长度均以一个页面为限,并且返回页面的起始地址
	if (retval < 0)
		goto out2;

	retval = copy_mount_options (data, &data_page);//将参数从用户空间复制到系统空间。这些参数值的长度均以一个页面为限,并且返回页面的起始地址
	if (retval < 0)
		goto out3;

	lock_kernel();
	retval = do_mount((char*)dev_page, dir_page, (char*)type_page,
			  flags, (void*)data_page);
	unlock_kernel();
	free_page(data_page);

out3:
	free_page(dev_page);
out2:
	putname(dir_page);
out1:
	free_page(type_page);
	return retval;
}
    其中flags为安装模式:
#define MS_RDONLY	 1	/* Mount read-only */
#define MS_NOSUID	 2	/* Ignore suid and sgid bits */
#define MS_NODEV	 4	/* Disallow access to device special files */
#define MS_NOEXEC	 8	/* Disallow program execution */
#define MS_SYNCHRONOUS	16	/* Writes are synced at once */
#define MS_REMOUNT	32	/* Alter flags of a mounted FS */
#define MS_MANDLOCK	64	/* Allow mandatory locks on an FS */
#define MS_NOATIME	1024	/* Do not update access times. */
#define MS_NODIRATIME	2048	/* Do not update directory access times */
#define MS_BIND		4096

/*
 * Flags that can be altered by MS_REMOUNT
 */
#define MS_RMT_MASK	(MS_RDONLY|MS_NOSUID|MS_NODEV|MS_NOEXEC|\
			MS_SYNCHRONOUS|MS_MANDLOCK|MS_NOATIME|MS_NODIRATIME)

/*
 * Magic mount flag number. Has to be or-ed to the flag values.
 */
#define MS_MGC_VAL 0xC0ED0000	/* magic flag number to indicate "new" flags */
#define MS_MGC_MSK 0xffff0000	/* magic flag number mask */

    所有的标志位都在低16位,而高16位则用作"magic_number"。


    do_mount是整个过程的核心,代码如下:

long do_mount(char * dev_name, char * dir_name, char *type_page, //dev_name指向了"/dev/sdb1",dir_name指向了"/mnt/sdb"
		  unsigned long flags, void *data_page)
{
	struct file_system_type * fstype;
	struct nameidata nd;
	struct vfsmount *mnt = NULL;
	struct super_block *sb;
	int retval = 0;

	/* Discard magic */
	if ((flags & MS_MGC_MSK) == MS_MGC_VAL)
		flags &= ~MS_MGC_MSK;
 
	/* Basic sanity checks */

	if (!dir_name || !*dir_name || !memchr(dir_name, 0, PAGE_SIZE))//dir_name指针不能为NULL,并且字符串的第一个字符不为NULL,即不是空字符串,并且字符串的长度不超过一个页面
		return -EINVAL;
	if (dev_name && !memchr(dev_name, 0, PAGE_SIZE))//如果dev_name指针非空,那么要求字符串的长度不得大于一个页面
		return -EINVAL;

	/* OK, looks good, now let's see what do they want */

	/* just change the flags? - capabilities are checked in do_remount() */
	if (flags & MS_REMOUNT)//暂不关心
		return do_remount(dir_name, flags & ~MS_REMOUNT,
				  (char *) data_page);

	/* "mount --bind"? Equivalent to older "mount -t bind" */
	/* No capabilities? What if users do thousands of these? */
	if (flags & MS_BIND)//暂不关心
		return do_loopback(dev_name, dir_name);

	/* For the rest we need the type */

	if (!type_page || !memchr(type_page, 0, PAGE_SIZE))//要求type_page指针不能为NULL,且字符串的
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值