当前位置: 首页 > web >正文

文件系统挂载详细分析(《图解Linux内核》虚拟文件系统篇笔记三)

上次说到文件查找和文件系统挂载的关系:文件系统挂载的时候创建了一个叫mnt的vfsmount结构体并穿越一堵堵墙在最后一堵墙后面垒上了自己的墙,而文件查找要在最后一堵墙上查找,而文件查找时穿越一堵堵墙的方式就是通过挂载时候建立的parent关系。所以说文件查找依赖于文件系统挂载

至此,有一个疑惑就是文件系统挂载的时候创建了一个vfsmount结构体的mnt,后续在这颗文件树下的文件查找的时候就是依赖于这个vfsmount来进行的:

例如像《图解Linux内核》书中提到的,有这样一个场景:

mkdir -p /a/b
sudo mount -t proc proc /a/b
sudo mount -t sysfs sysfs /a/b
#分析查找/a/b/cl的过程

那么比如/a/b是处于ext4文件系统的,那么在查找a文件夹或者b文件夹的时候,第一次调用walk_component方法的时候(walk_component方法是用来处理一层目录的,或者说是根据nd当前查找的结果查找下一级目录的),nd->path.dentry指向的是/目录(根目录),nd->last代表的是a,即在/下面查找a,那么假如没有在/下面找到a这个dentry,就会创建一个(lookup_slow):

static const char *walk_component(struct nameidata *nd, int flags)
{struct dentry *dentry;if (unlikely(nd->last_type != LAST_NORM)) {if (!(flags & WALK_MORE) && nd->depth)put_link(nd);return handle_dots(nd, nd->last_type);}//根据当前nd查询结果,查找有没有想要的dentry,有的话直接返回dentry = lookup_fast(nd);if (IS_ERR(dentry))return ERR_CAST(dentry);if (unlikely(!dentry)) {//如果没有想要的dentry,就创建一个dentry = lookup_slow(&nd->last, nd->path.dentry, nd->flags);if (IS_ERR(dentry))return ERR_CAST(dentry);}if (!(flags & WALK_MORE) && nd->depth)put_link(nd);return step_into(nd, flags, dentry);
}

然后step_into用来处理翻越一堵堵墙以及更新nd->path:

static const char *step_into(struct nameidata *nd, int flags,struct dentry *dentry)
{struct path path;struct inode *inode;//翻越一堵堵墙,path会存放当前目录所在的最外层的文件系统,也就是ext4int err = handle_mounts(nd, dentry, &path);nd->path = path;return NULL;
}
static inline int handle_mounts(struct nameidata *nd, struct dentry *dentry,struct path *path)
{bool jumped;int ret;path->mnt = nd->path.mnt;path->dentry = dentry;ret = traverse_mounts(path, &jumped, &nd->total_link_count, nd->flags);if (jumped) {if (unlikely(nd->flags & LOOKUP_NO_XDEV))ret = -EXDEV;elsend->state |= ND_JUMPED;}if (unlikely(ret)) {dput(path->dentry);if (path->mnt != nd->path.mnt)mntput(path->mnt);}return ret;
}
static int __traverse_mounts(struct path *path, unsigned flags, bool *jumped,int *count, unsigned lookup_flags)
{struct vfsmount *mnt = path->mnt;while (flags & DCACHE_MANAGED_DENTRY) {if (flags & DCACHE_MOUNTED) {	// something's mounted on it..struct vfsmount *mounted = lookup_mnt(path);//当前目录下挂载了文件系统if (mounted) {		// ... in our namespacedput(path->dentry);if (need_mntput)mntput(path->mnt);//更新当前文件系统path->mnt = mounted;//更新当前目录path->dentry = dget(mounted->mnt_root);// here we know it's positiveflags = path->dentry->d_flags;need_mntput = true;continue;}}}return ret;
}

那么第一次在/下面查找a的时候,/a这个目录是没有挂载文件系统的,那么handle_mounts是不会修改path的,也就是不会修改当前的dentry的。

然后再回到walk_component函数,在当前目录/a下找b,和a一样最后把当前dentry改成/a/b,而找到b之后,因为/a/b下面挂载了文件系统,所以handle_mounts会先把path->mnt改成proc、把path->dentry改成/root,再把path->mnt改成sysfs、把path->dentry改成/root。这样就找到了最后一堵墙,然后再执行walk_component在sysfs文件系统的/root下找c。

那么这个vfsmount结构体到底是啥?里面包含的这个inode是查找整颗文件树的起点,它究竟怎么创建出来的?不同的文件系统创建这个根inode的方式有何不同,创建出来的根inode又有何区别?

http://www.xdnf.cn/news/19075.html

相关文章:

  • 神经网络为何能 “学习”?从神经元到深度学习模型的层级结构解析
  • 打破存储局限:CS 创世 SD NAND 如何优化瑞芯微(RK)与北京君正平台的贴片式 SD 卡性能
  • 【C++成长之旅】C++入门基础:从 Hello World 到命名空间与函数重载的系统学习
  • Bscan Bonding Chain
  • 印度尼西亚数据源 PHP 对接文档
  • Mysql——分库分表
  • Redis发布订阅:实时消息系统的极简解决方案
  • 从数字到价值:ESG评级的深层变革
  • Linux827 测试
  • 计算机日常答疑,一起寻找问题的最优解
  • LeetCode算法日记 - Day 24: 颜色分类、排序数组
  • PyTorch图像预处理完全指南:从基础操作到GPU加速实战
  • 完整实验命令解析:从集群搭建到负载均衡配置(2)
  • [vcpkg] Windows入门使用介绍
  • day22 回溯算法part01
  • 服务器类型与TCP并发服务器构建(SELECT)
  • 设计模式:桥接模式(Bridge Pattern)
  • 《Linux内存管理:实验驱动的深度探索》【附录】【实验环境搭建 7】【使用buildroot方式构建文件系统】
  • 【开发便利】让远程Linux服务器能够访问内网git仓库
  • 链表-25.k个一组翻转链表-力扣(LeetCode)
  • 深入解析 Flink Function
  • Vue将内容生成为二维码,并将所有二维码下载为图片,同时支持批量下载(下载为ZIP),含解决一次性生成过多时页面崩溃解决办法
  • TCP 并发服务器构建
  • 智芯MCU 勘误文档问题解析
  • 【Java知识】Java线程相关对象全面解析与最佳实践
  • 阿里云——应用交付与负载均衡
  • 数据对话的“通用语法”:SQL与KingbaseES的智能处理艺术
  • 从感知机到大模型:神经网络的全景解析与实践指南
  • ES01-环境安装
  • 盛大启幕!融智兴科技亮相 IOTE 2025 深圳国际物联网展