[文件系统]文件系统学习笔记(八)---mount系统调用(代码相关)
来源:互联网 发布:企汇网发布信息软件 编辑:程序博客网 时间:2024/06/06 17:42
一,mount系统调用--相关代码
源码位置:kernel/fs/Namespace.c文件的do_mount()函数,
long do_mount(char *dev_name,char*dir_name,char*type_page,unsigned long flags,void *data_page)
if (!dir_name || !*dir_name || !memchr(dir_name, 0, PAGE_SIZE)) return -EINVAL;dev_name指的是要挂载文件系统的名字,如tmpfs,
dir_name指的是文件系统要被挂载的目标目录
type_page指的是要挂载的文件系统的类型
flags指的是挂载选项,如MS_RDONLY等等
data_page指的是一些额外选项等,如wait关键字
1,do_mount()函数首先会做一些参数检查,dir_name不能为空并且大小不能超过一个PAGE大小,将data_page超过一个PAGE大小的部分截断。
if(!memchr(dir_name,0,PAGE_SIZE))
检查data_page的长度是否超过一个page,如果超过,则将超出的部分截断。
if (data_page)
((char *)data_page)[PAGE_SIZE - 1] = 0;
do_mount()函数首先调用kern_path()函数,将dir_name转换为struct path结构体,
struct path{ struct vfsmount *mnt; struct dentry *dentry; };
2,然后根据不同的flag参数去设置不同的mnt_flags临时变量,如果flag中没有包含MS_REMOUNT,MS_BIND,MS_MOVE,MS_SHARED,MS_PRIVATE,等,那么最后会调do_new_mount()函数。
3,do_new_mount()函数
static int do_new_mount(struct path*path,char*type,int flags,int mnt_flags,char*name,void*data)
path参数是dir_name经过kern_path()转换后的path结构体
type参数指的是文件系统的类型
flags参数指的是一些mount选项
mnt_flags参数指的是一些monut选项
name参数指的是要挂载文件系统的名字,如tmpfs
data参数指的是一些额外选项等,如wait关键字
do_new_mount()函数首先调用do_kern_mount(type,flags,name,data)函数,该函数的作用是建立一块新的安装块区域,获取一个vfsmount实例,获取源文件系统vfsmount结构,并通过特定文件系统的操作装载到系统系统中,返回装载点的根目录,然后调用do_add_mount(real_mount(mnt),path,mnt_flags)函数,该函数的作用是将mount实例挂载到mount树上去,将源文件系统增加到目的文件系统中。
1651 static int do_new_mount(struct path *path, char *type, int flags,1652 int mnt_flags, char *name, void *data)1653 {1654 struct vfsmount *mnt;1655 1656 if (!type)1657 return -EINVAL;1658 1659 /* we need capabilities... */1660 if (!capable(CAP_SYS_ADMIN))1661 return -EPERM;1662 1663 lock_kernel();1664 mnt = do_kern_mount(type, flags, name, data);1665 unlock_kernel();1666 if (IS_ERR(mnt))1667 return PTR_ERR(mnt);1668 1669 return do_add_mount(mnt, path, mnt_flags, NULL);1670 }
do_kern_mount()函数细节,do_kern_mount()首先调用get_fs_type()函数返回要挂载文件系统的file_system_type实例,file_system_type是在各个文件系统在系统启动的时候 注册进内核的,所有注册的文件系统形成一个单链表,然后do_kern_mount()调用vfs_kern_mount()函数,vfs_kern_mount()函数的作用是分配一个struct mount结构体,然后vfs_kern_mount()调用各个文件系统file_system_type结构的mount成员函数(如ext4则会调用ext4_mount函数),该函数的作用是创建该文件系统的超级快对象,返回该文件系统的根目录(root)的dentry实例,最后将创建的超级快对象赋值给新创建的vfsmount结构所指的超级快,同时vfsmount所指的mnt_root点赋值为超级快所指的根dentry.
do_add_mount()函数细节,该函数作用是将当前mount实例加到mount树上,do_add_mount()函数的两个关键点,lock_mount()函数和graft_tree()函数,lock_mount()检查如果当前要挂载的目录之前已经挂载其它文件系统,则要进行文件系统切换动作,graft是嫁接的意思,是将将要mount的目录树与当前目录的文件系统的目录树连接起来,很像嫁接技术,而原来文件系统的目录树没损伤。
lock_mount()函数主要调用lookup_mnt()函数,该函数返回一个struct vfsmount的实例,lookup_mnt()函数调用__lookup_mnt()函数返回一个struct mount的实例,在同个父文件系统下的同个目录可以作为多个子文件系统的挂载点,所以如果真的挂载了多个子文件系统,那么这几个子文件系统通过散列函数肯定会被放在哈希表里的同一条链表上。__lookup_mnt()函数就是返回该目录下最后挂载的文件系统mount的实例。__lookup_mnt()函数如下所示:
414 struct vfsmount *__lookup_mnt(struct vfsmount *mnt, struct dentry *dentry,415 int dir)416 {417 struct list_head *head = mount_hashtable + hash(mnt, dentry);418 struct list_head *tmp = head;419 struct vfsmount *p, *found = NULL;420 421 for (;;) {422 tmp = dir ? tmp->next : tmp->prev;423 p = NULL;424 if (tmp == head)425 break;426 p = list_entry(tmp, struct vfsmount, mnt_hash);427 if (p->mnt_parent == mnt && p->mnt_mountpoint == dentry) {428 found = p;429 break;430 }431 }432 return found;433 }
graft_tree()函数的实现细节,graft_tree()函数主要调用attach_recursive_mnt()函数,static int attach_recursive_mnt(struct mount*source_mnt,struct path*path,struct path*parent_path),attach_recursive_mnt()函数做的主要操作是1.通过mnt_set_mountpoint()将子vfsmount中的mnt_parent指向父vfsmount,将子vfsmount的mnt_mountpoint指向位于父文件系统中的挂载点dentry;2.通过commit_tree()将子文件系统添加到内核的文件系统哈希表中,并将子文件系统添加到父文件系统对应的子文件系统链表中;
commit_tree()函数的作用是1.将当前文件系统的名字空间设置为父名字空间,父vfsmount通过当前vfsmount中的mnt_parent获取;再将其连接到父名字空间链表中。2.将当前vfsmount加入到对应哈希值的冲突链表当中,哈希值通过hash()计算。其中,mnt_hash作为链表元素。3.将当前vfsmount加入到父vfsmount对应的子文件系统链mnt_mounts中。其中,mnt_child作为链表元素。
- [文件系统]文件系统学习笔记(八)---mount系统调用(代码相关)
- [文件系统]文件系统学习笔记(五)---mount系统调用(1)
- [文件系统]文件系统学习笔记(十一)——mount系统调用(其它)
- Linux系统编程学习笔记(3)-Linux文件系统与相关函数调用
- [文件系统]文件系统学习笔记(二)---task_struct
- [文件系统]文件系统学习笔记(九)---rootfs
- [文件系统]文件系统学习笔记(十)---杂项
- 系统编程概念(文件系统mount等函数的使用)
- Linux文件系统学习(四)之read open系统调用
- linux文件系统调用(1)---mount
- Linux内核源码分析-安装普通文件系统-mount系统调用
- linux文件系统(学习笔记)
- Linux学习笔记(文件系统)
- Linux学习笔记(文件系统)
- [文件系统]文件系统学习笔记(十一)——部分代码详解
- Linux学习笔记(5)-Linux系统文件系统结构
- [文件系统]read系统调用剖析(一)
- [文件系统]read系统调用剖析(二)
- Handler-接受子线程数据更新UI主线程;非主线程通信--HandlerThread
- IOS应用程序多语言本地化解决方案(转)
- 12.12.3 把异常传递给控制台
- 给大家分享网站源码有12.9G需要的自己去下载吧
- 翻译经典 HDFS 原理讲解漫画 之三---容错和副本布局策略
- [文件系统]文件系统学习笔记(八)---mount系统调用(代码相关)
- poj-2446
- Multiple markers at this line
- Android EditText 的onKeyDown事件无法捕获问题
- 这个循环让我混乱了,希望懂的人指点一下
- poj 2524 Ubiquitous Religions(并查集)
- Android广播机制
- VS2010编译Project时会出“error LNK1123” 错误
- 服务器大量的last