基础知识在<深入linux内核架构>第8章,自行脑补.

看下几个关键的过程:

do_add_mount里有重要函数lock_mount, lock_mount函数的输入是struct path, 输出是struct mountpoint:

    struct path {
struct vfsmount *mnt;
struct dentry *dentry;
};
    struct mountpoint {
struct hlist_node m_hash;
struct dentry *m_dentry;
struct hlist_head m_list;
int m_count;
};
struct vfsmount {
struct dentry *mnt_root; /* root of the mounted tree */
struct super_block *mnt_sb; /* pointer to superblock */
int mnt_flags;
};

path 由 filename_lookup 得到, 其中vfsmount是当前文件系统的挂载信息, dentry是通过文件名得出的最后一级目录的dentry(比如,/mnt/dir1/dir2/,那么此时dentry对应的就是dir2的dentry.

函数: m_hash(struct vfsmount *mnt, struct dentry *dentry)

二元组<mnt, dentry>可以确定什么东西? 这个二元组可以唯一确定当前目录树中的一个目录[感觉直接用一个dentry也可以得到啊! 但是用两个参数可能散列效果更好?] ,这样可以直接得到一个下标(下标是mount_hashtable的下标). mount_hashtable是个什么事情?

这个就是函数m_hash的输出了:mount_hashtable[tmp & m_hash_mask].

我们发现,原来所有mount结构体都是通过链接元素mnt_hash链接到mount_hashtable[**]中去的,所以当我们发现了这个链表之后,就可以通过这个链表得到在这个开链上的所有的mount结构体!这里就得到了一个很重要的信息[所有的mount信息都在一个散列表mount_hashtable上维护]

这样我们就可以找到一个挂载点的所有的挂载信息了!

lookup_mnt还算是比较复杂的, 涉及到一个挂载点上挂载了多个"磁盘", lookup会找到最早的挂载的磁盘, 这个可以以后看, 现在我们只需要知道lookup_mnt发到了vfsmount结构体就可以了!

另一个函数:lookup_mountpoint(struct dentry *dentry), 这个函数在是通过dentry项, 找到全局数组&mountpoint_hashtable中的一个开链:mountpoint_hashtable[tmp & mp_hash_mask];

这里也得到一个很重要的信息:

[所有的mountpoing信息都是在一个全局的散列表mountpoint_hashtable上维护]

mountpoint 和 vfsmount有什么区别?

struct mountpoint {
struct hlist_node m_hash;
struct dentry *m_dentry;
struct hlist_head m_list;
int m_count;
};

mountoint只和dentry相关,

所以说lock_mount到最后就是得到一个mountpoint,

-------------------------

无关:

函数vfs_kern_mount(struct file_system_type *type, int flags,  const char *name, void *data)

首先根据文件名, 分配 mount 结构体, alloc_vfsmnt(name),

然后调用mount_fs函数得到fs相对根目录dentry,

根据dentry,初始化mount结构体, 然后根据返回mount结构提中的vfsmount成员.

--------------------------

attach_recursive_mnt是最终把这些散乱的东西链接在一起的函数

static int attach_recursive_mnt(struct mount *source_mnt,

                struct mount *dest_mnt, 

                struct mountpoint *dest_mp,

                struct path *parent_path)

各参数中, source_mnt当前新的挂载信息, dest_mnt是父挂载信息, dest_mp是挂载点的信息, parent_path是路径的信息

内核代码中这个函数头的注释我也是醉了, 好大一长串, (其中涉及到mount的属性:shared, private, slave, unbindable 等等), 之所以这么复杂, 是因为考虑到namespace的东西,这个也是将来要看的,看下docker到底是个神马东西!

===========

mount这一块确实有看头哈,看下到底怎么通过挂载点把资源给隔离开!

主要看函数:mnt_set_mountpoint (struct mount *mnt, struct mountpoint *mp, struct mount *child_mnt)

首先,mountpoint是怎么来的? mountpoint通过dentry而来, 上来之后,先把

mp->m_count++; 然后设置子mount 的 mnt_parent 为 父mount , 子mount的mnt_mountpoint点设置成mp->m_dentry, mountpoint中有一个串联所有mount信息的一个链叫做m_list, 这个链里面会把该mountpoint下面所有的mount链接在一起.

===========

3.6 commit_tree()

1.将当前文件系统的名字空间设置为父名字空间,父vfsmount通过当前vfsmount中的mnt_parent获取;再将其连接到父名字空间链表中。

2.将当前vfsmount加入到对应哈希值的冲突链表当中,哈希值通过hash()计算。其中,mnt_hash作为链表元素。

3.将当前vfsmount加入到父vfsmount对应的子文件系统链表mnt_mounts中。其中,mnt_child作为链表元素。

从整个挂载的处理流程上看,挂载的本质就是将源文件系统的vfsmount结构连接到目的文件系统对应的vfsmount结构中,即具体涉及到两个vfsmount中字段的指向问题。两个vfsmount具体父子等级关系,这也对应着内核中目录树的父子等级关系。

关键函数:commit_tree(struct mount *mnt, struct mount *shadows)

1 将子文件系统的命名空间设置成父命名空间, 父vfsmount通过当前vfsmount中的mnt_parent获取; 再将其联街道父命名空间列表中去.

2 将当前vfsmount加入到对应哈希值的冲突链表中去,

3 将当前vfsmount加入到父vfsmount对应的子文件系统链表mnt_mounts中去,

VFS分析(一)挂载(持续更新)的更多相关文章

  1. 为了解决mysqlbing翻译表字段问题而分析frm文件(持续更新)

    出处:kelvin19840813 的博客 http://www.cnblogs.com/kelvin19840813/ 您的支持是对博主最大的鼓励,感谢您的认真阅读.本文版权归作者所有,欢迎转载,但 ...

  2. Linux命令(持续更新ing)

    *.命令语法:  a.在进行参数设定时,通常为“-”号,若为完整参数名称,则输入“--”符号;  b.指令太长的时候,可以使用“\”符号使指令连续到下一行;  c.各种符号的意义:    ''     ...

  3. Linux面试题(史上最全、持续更新、吐血推荐)

    文章很长,建议收藏起来,慢慢读! 疯狂创客圈为小伙伴奉上以下珍贵的学习资源: 疯狂创客圈 经典图书 : <Netty Zookeeper Redis 高并发实战> 面试必备 + 大厂必备 ...

  4. 我的敏捷、需求分析、UML、软件设计电子书 - 下载(持续更新中)

    我将所有我的电子书汇总在一起,方便大家下载!(持续更新) 文档保存在我的网站——软件知识原创基地上(www.umlonline.org),请放心下载. 1)软件设计是怎样炼成的?(2014-4-1 发 ...

  5. 干货!IT小伙伴们实用的网站及工具大集合!持续更新!

    1.Git 还在担心自己辛辛苦苦写的代码被误删了吗?还在担心自己改错了代码不能挽回吗?还在苦恼于多人开发合作找不到一个好的工具吗?那么用Git就对 了,Git是一个开源的分布式版本控制系统,用以有效. ...

  6. java视频教程 Java自学视频整理(持续更新中...)

    视频教程,马士兵java视频教程,java视频 1.Java基础视频 <张孝祥JAVA视频教程>完整版[RMVB](东西网) 历经5年锤炼(史上最适合初学者入门的Java基础视频)(传智播 ...

  7. BLE资料应用笔记 -- 持续更新

    BLE资料应用笔记 -- 持续更新 BLE 应用笔记 小书匠 简而言之,蓝牙无处不在,易于使用,低耗能和低使用成本.'让我们'更深入地探索这些方面吧. 蓝牙无处不在-,您可以在几乎每一台电话.笔记本电 ...

  8. ( 译、持续更新 ) JavaScript 上分小技巧(三)

    最近家里杂事较多,自学时间实在少的可怜,所以都在空闲时间看看老外写的内容,学习之外顺便翻译分享~等学习的时间充足些再写写自己的一些学习内容和知识点分析(最近有在接触的:复习(C#,SQL).(学习)T ...

  9. 关于ASP.NET MVC开发设计中出现的问题与解决方案汇总 【持续更新】

    最近一直用ASP.NET MVC 4.0 +LINQ TO SQL来开发设计公司内部多个业务系统网站,在这其中发现了一些问题,也花了不少时间来查找相关资料或请教高人,最终都还算解决了,现在我将这些问题 ...

随机推荐

  1. jQuery.merge()

    jQuery.merge( first, second ) //返回Array 合并两个数组内容到第一个数组. first第一个用来合并的数组,元素是第二数组加进来的. second第二个数组合并到第 ...

  2. SMW0上传EXCEL模板时报错无分配给对象***的MIME类型

    在使用SMW0上传照片.声音文件.EXCEL模板等文件时,遇到报错提示,如下图所示: 解决办法:需要先维护 .XLS 文件的MIME TYPE,SMW0 打开如下图所示 选择上图红色框中“WebRFC ...

  3. Java中字节流和字符流的比较(转)

    字节流与和字符流的使用非常相似,两者除了操作代码上的不同之外,是否还有其他的不同呢? 实际上字节流在操作时本身不会用到缓冲区(内存),是文件本身直接操作的,而字符流在操作时使用了缓冲区,通过缓冲区再操 ...

  4. App开发流程之数据持久化和编译静态链接库

    先记录数据持久化. iOS客户端提供的常用数据持久化方案:NSUserDefaults代表的用户设置,NSKeydArchiver代表的归档,plist文件存储,SQLite数据库(包括上层使用的Co ...

  5. 【读书笔记】iOS-防止通讯协议被轻易破解的方法

    开发者可以选择类似Protobuf之类的二进制通讯协议或者自己实现通讯协议,对于传输的内容进行一定程度的加密,以增加黑客破解协议的难度. 参考资料: <iOS开发进阶> --唐巧

  6. 安卓第十三天笔记-服务(Service)

    安卓第十三天笔记-服务(Service) Servcie服务 1.服务概念 服务 windows 服务没有界面,一直运行在后台, 运行在独立的一个进程里面 android 服务没有界面,一直运行在后台 ...

  7. HTML5 拖放

    拖放(Drag 和 drop)是 HTML5 标准的组成部分. 拖放 拖放是一种常见的特性,即抓取对象以后拖到另一个位置. 在 HTML5 中,拖放是标准的一部分,任何元素都能够拖放. 浏览器支持 I ...

  8. iOS多线程-01-pthread与NSTread

    简介 恰当的使用多线程编程可以提供任务的执行效率和系统资源的利用率 多线程是为了提高资源利用率,和应用程序的响应速度,多个线程共享应用资源 每个应用程序都有一个主线程,通常用来做UI界面刷新等 比较耗 ...

  9. Hive安装与配置(靠谱亲测)

     Hive是hadoop生态环境的组成之一.通过Hive,可以使得直接用SQL操作HDFS.最大的好处就是让熟悉SQL,但是不了解JAVA的数据分析师使用.其机制就是一个将SQL语言转化为MapRed ...

  10. 《ASP.NET MVC 5 框架揭秘》

    <ASP.NET MVC 5 框架揭秘> 基本信息 作者: 蒋金楠 出版社:电子工业出版社 ISBN:9787121237812 上架时间:2014-8-1 出版日期:2014 年8月 开 ...