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

文件系统挂载详细分析(《图解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.dtcms.com/a/355051.html

相关文章:

  • [机械结构设计-48]:机械工程师的岗位要求
  • ArkUI框架之promptAction弹窗
  • 安卓开发---BLE通信
  • 基于STM32单片机的车牌识别设计
  • clcd土地利用数据分类
  • Tree Shaking原理
  • SOME/IP-SD事件组订阅
  • 昆泰芯离轴应用技术与产业链协同助力机器人关节产业实现技术突破
  • TDengine 数据订阅支持 MQTT 协议用户手册
  • 本地消息表实现分布式事务保证最终一致性
  • Java框架搭建实用开发
  • DPIN亮相DePIN Expo 2025,定义“DePIN 2.0”企业级应用新范式
  • Linux中Java后端调用外部进程 未处理后台输出流 导致io阻塞问题解决方法
  • K8S架构与组件完全解析
  • Baselight 携手 Walrus 激活链上数据价值,打造无需许可的数据中
  • LeetCode热题100--98. 验证二叉搜索树--中等
  • QT 概述(背景介绍、搭建开发环境、Qt Creator、程序、项目文件解析、编程注意事项)
  • Fortran快速排序算法实现与优化
  • Web安全:深入理解User-Agent报头注入与防御
  • 从CTFshow-pwn入门-pwn43理解栈溢出到底跳转call还是plt
  • 网络安全测试(一)Kali Linux
  • PyTorch实战(3)——PyTorch vs. TensorFlow详解
  • 网络安全设备监控指标
  • jvm锁优化
  • MiniCPM-V 4.5 vs MiniCPM-V 2.6 深度对比分析
  • claude code helper for vscode
  • MTK Linux DRM分析(十七)- MTK KMS实现mtk_drm_fb.c
  • HTML贪吃蛇游戏实现
  • SQLSERVER触发器
  • C++讲解---什么是静态成员函数