用户访问文件的可见性与路径解析完全由其所属进程的挂载命名空间mnt namespace及其内部的挂载树mount tree决定。挂载树是内核为每个 mnt ns 维护的独立挂载点集合决定了进程能看到哪些文件系统、路径对应哪些实际内容。核心概念挂载命名空间mnt namespaceLinux 最早的命名空间2.4.19隔离进程的文件系统挂载视图。每个进程通过task_struct-nsproxy-mnt_ns关联一个 mnt ns。挂载树mount treemnt ns 内由struct mount构成的树状结构记录所有挂载点、挂载源、传播类型与层次关系。用户访问文件用户通过进程发起文件操作open/read/write内核按进程所属 mnt ns 的挂载树解析路径、定位 inode 并做权限检查。挂载树与 mnt ns 的内核结构struct mnt_namespace代表一个 mnt ns包含根挂载点root、挂载计数、列表等。struct mount代表一个挂载实例含mnt_parent父挂载、mnt_mountpoint挂载点 dentry、mnt_namespace所属 ns、传播类型等。struct path进程的根 / 当前目录含mnt挂载实例与dentry目录项是路径解析的起点。用户访问文件的完整流程路径解析起点进程的current-fs-root根目录与current-fs-pwd当前目录均为struct path绑定到所属 mnt ns。逐层解析内核从起点 dentry 出发遍历路径分量如/a/b/c遇到目录项标记DCACHE_MOUNTED挂载点时切换到对应的子挂载struct mount。按 mnt ns 的挂载树遍历直到找到目标文件的 inode。可见性隔离不同 mnt ns 的挂载树不同同一路径可能对应不同 inode / 内容同 ns 内进程共享同一挂载树视图。权限检查路径解析成功后用进程的真实 UID/GID 与文件 inode 的 UID/GID 做 UGO/ACL 权限判断与 user ns 映射相关但可见性由 mnt ns 决定。mnt ns 与挂载树的生命周期初始 ns系统启动时 init 进程创建初始 mnt ns全局唯一根挂载树。创建新 nsclone(CLONE_NEWNS)或unshare(CLONE_NEWNS)触发copy_mnt_ns复制当前 ns 的挂载树到新 ns新 ns 初始与父 ns 一致后续独立修改。挂载 / 卸载mount()/umount()仅修改当前进程所属 mnt ns 的挂载树默认 private 模式下不影响其他 nsshared/slave 模式可跨 ns 传播。共享 / 进入 nssetns()/nsenter可让进程加入其他 mnt ns立即切换到该 ns 的挂载树视图。关键特性共享子树传播类型控制挂载 / 卸载事件在 ns 间的传播默认 privateprivate完全隔离不传播也不接收传播。shared同对等组内双向传播。slave仅接收来自 master 的传播不反向传播。unbindable不可作为挂载点也不传播。核心角色概念作用内核结构open用户发起打开文件的系统调用入口sys_open/do_sys_openpath文件路径字符串/a/b/c内核要解析它struct pathmnt ns挂载命名空间决定能看到什么文件系统struct mnt_namespacedentry目录项路径的内存缓存节点快速定位文件struct dentrycurrent-fs-rootcurrent-fs-root是Linux 内核中用于获取当前进程的根目录的核心表达式是内核操作进程文件系统根路径的标准方式。每个进程都有独立的根目录普通进程默认是系统根目录/chroot后的进程根目录是自定义目录current-fs-root是内核获取这个根目录的唯一标准入口。内核要为进程打开/etc/passwd这类绝对路径时必须以current-fs-root为起点解析路径这是 Linux 文件系统的基础规则内核检查进程能否访问某个文件时会用它判断进程的根目录边界比如chroot监狱的进程无法访问根目录之外的文件。不同进程的current-fs-root可以不同例如容器、chroot环境内核通过它实现进程间文件系统根目录隔离。和current-fs-pwd的区别current-fs-root进程根目录/current-fs-pwd进程当前工作目录./current-fs-root是struct path结构体包含mnt挂载点信息dentry目录项文件系统中的目录实体current-fs-pwdcurrent-fs-pwd是Linux 内核中获取 ** 当前进程的工作目录Current Working Directory, CWD** 的标准表达式是内核定位进程相对路径的核心。进程使用./test.txt、../data/log这类相对路径时内核必须用current-fs-pwd作为起点拼接成完整路径。没有它内核无法识别相对路径这是cd、ls、./程序等命令能正常工作的基础每个进程都有独立的工作目录你在终端cd /home/user该终端下运行的所有进程pwd都会指向这里不同进程可以拥有完全不同的工作目录内核实现系统调用cd、pwd、open打开相对路径文件、mkdir等命令底层都依赖current-fs-pwd。current-fs-pwd是struct path结构体包含mnt挂载点dentry目录项目录实体信息内核代码中常用来获取当前目录路径字符串拼接相对路径检查文件访问权限文件 open 全过程用户调用open(path)→ 内核用「当前进程的 mnt ns」做隔离 → 遍历「挂载树」解析路径 → 找到目标「dentry inode」→ 成功打开文件核心路径解析 100% 受当前进程的 mnt ns 控制dentry 是路径解析的最终产物。用户触发open(/a/b/c, O_RDONLY)用户 / 进程执行系统调用传入字符串路径内核开始工作。锁定「上下文」获取当前进程的 mnt ns内核第一步current-nsproxy-mnt_ns // 当前进程所属的挂载命名空间 current-fs-root // 进程根目录struct path current-fs-pwd // 进程当前目录struct path这一步决定了文件可见性不同 mnt ns同一个路径解析出完全不同的文件。容器、chroot、unshare 隔离全靠这一步。路径解析核心从字符串 → 挂载树 → dentry内核执行path_lookup()/do_path_lookup()这是最关键环节起点从进程的root或pwdstruct path开始逐层解析/a/b/c先找a目录的dentry再找b目录的dentry最后找c文件的dentry挂载点检测遇到dentry标记DCACHE_MOUNTED→ 说明是挂载点内核切换到 mnt ns 挂载树里的子文件系统继续解析后续路径终点得到目标文件的struct pathstruct path { struct vfsmount *mnt; // 归属的文件系统来自mnt ns struct dentry *dentry; // 最终找到的目录项 };最终打开拿到 dentry inode生成 fd由dentry-d_inode拿到文件元数据权限检查、打开模式检查分配file结构体返回文件描述符fd给用户关键数据结构关系进程 task_struct └── mnt_namespace 挂载命名空间隔离视图 └── mount tree 挂载树所有挂载点 └── 路径解析 lookup └── struct path ├── vfsmount 所在文件系统 └── dentry 目录项缓存最终目标 └── inode 真实文件核心要点1. mnt ns 只决定「可见性」不决定权限mnt ns能不能看到这个文件 / 路径权限UID/GID、ACL、LSM 决定能不能打开 / 读写2. dentry 是内核缓存极大加速路径解析不直接读磁盘目录直接查内存dentry缓存每个 dentry 唯一对应一个路径分量挂载点就是带标记的特殊 dentry3. 同一个路径字符串不同 mnt ns → 不同 dentry这就是容器文件隔离的本质宿主机 mnt ns/etc/hosts是宿主机文件容器 mnt ns/etc/hosts是容器内文件路径一样解析出的dentry完全不同