当前 DragonOS 的挂载逻辑中,MountList 使用 MountPath 字符串记录和维护挂载关系。创建新挂载、bind mount、recursive bind、move mount、FUSE/virtiofs submount 等路径中,都需要保存或反查挂载点路径。
这导致挂载子系统在一些场景下依赖 inode.absolute_path() 或路径字符串重写来恢复 mount namespace 中的真实位置。但 absolute_path() 并不是一个可靠的 mountpoint 来源:普通文件系统 inode 不一定知道自己位于哪个 mount namespace 路径;FUSE/virtiofs 可能返回 fuse:<nodeid> 这类 synthetic name;bind/move/覆盖挂载后,同一个 inode 也可能对应多个路径。
具体风险
absolute_path() 的语义混杂:一部分实现返回真实路径,另一部分特殊 inode 返回 display name,例如 eventfd、epoll、pipe、fuse:<nodeid>。
- bind mount 后,同一个 inode/subtree 可能出现在多个路径下,单个字符串无法唯一代表挂载位置。
- 路径规范化问题会影响匹配,例如 symlink、
.、..、相对路径和绝对路径可能指向同一对象但字符串不同。
MS_MOVE 需要递归改写子挂载路径,容易出现漏改、顺序错误或 mount list 与真实拓扑不一致。
- recursive bind 依赖
strip_prefix 之类字符串前缀匹配判断子挂载归属,语义上比遍历 mount tree 脆弱。
- stacked mount / overmount 场景下,多个 mount 可能共享同一个 mountpoint 字符串,但实际 top mount、covered mount、parent mount 关系不同。
- 不同 mount namespace、
chroot、pivot_root 后,同一挂载对象在不同视角下的展示路径可能不同,单个全局路径字符串难以准确表达。
- 特殊 inode 或匿名 inode 没有稳定 namespace path,容易把 display name 误用于 mount 拓扑逻辑。
Linux 的做法
Linux 不依赖 inode 反查字符串路径来维护挂载拓扑。mount(2) 入口会先把用户路径解析为:
struct path {
struct vfsmount *mnt;
struct dentry *dentry;
};
后续 path_mount()、do_new_mount()、do_loopback()、do_move_mount() 都传递 struct path。挂载关系记录的是:
parent mount + mountpoint dentry
而不是某个 inode 反查出来的字符串路径。字符串路径只在 /proc/mounts、mountinfo、d_path() 等展示或用户接口场景中临时生成。
建议方向
长期应考虑将 DragonOS mount 拓扑从字符串路径模型迁移到对象引用模型。例如引入类似 Linux struct path 的结构:
struct VfsPath {
mount: Arc<MountFS>,
inode: Arc<MountFSInode>, // DragonOS现在还是没有dentry抽象,见 #1774
}
让 mount、bind mount、move mount、recursive bind、submount 等核心逻辑基于 MountFS + mountpoint inode/dentry 对象关系操作,而不是基于 MountPath 字符串做查找和前缀匹配。
MountPath 字符串可以继续用于展示、调试和用户态接口输出,但不应作为核心 mount 拓扑的一致性来源。
当前 DragonOS 的挂载逻辑中,
MountList使用MountPath字符串记录和维护挂载关系。创建新挂载、bind mount、recursive bind、move mount、FUSE/virtiofs submount 等路径中,都需要保存或反查挂载点路径。这导致挂载子系统在一些场景下依赖
inode.absolute_path()或路径字符串重写来恢复 mount namespace 中的真实位置。但absolute_path()并不是一个可靠的 mountpoint 来源:普通文件系统 inode 不一定知道自己位于哪个 mount namespace 路径;FUSE/virtiofs 可能返回fuse:<nodeid>这类 synthetic name;bind/move/覆盖挂载后,同一个 inode 也可能对应多个路径。具体风险
absolute_path()的语义混杂:一部分实现返回真实路径,另一部分特殊 inode 返回 display name,例如eventfd、epoll、pipe、fuse:<nodeid>。.、..、相对路径和绝对路径可能指向同一对象但字符串不同。MS_MOVE需要递归改写子挂载路径,容易出现漏改、顺序错误或 mount list 与真实拓扑不一致。strip_prefix之类字符串前缀匹配判断子挂载归属,语义上比遍历 mount tree 脆弱。chroot、pivot_root后,同一挂载对象在不同视角下的展示路径可能不同,单个全局路径字符串难以准确表达。Linux 的做法
Linux 不依赖 inode 反查字符串路径来维护挂载拓扑。
mount(2)入口会先把用户路径解析为:后续 path_mount()、do_new_mount()、do_loopback()、do_move_mount() 都传递 struct path。挂载关系记录的是:
而不是某个 inode 反查出来的字符串路径。字符串路径只在 /proc/mounts、mountinfo、d_path() 等展示或用户接口场景中临时生成。
建议方向
长期应考虑将 DragonOS mount 拓扑从字符串路径模型迁移到对象引用模型。例如引入类似 Linux struct path 的结构:
让 mount、bind mount、move mount、recursive bind、submount 等核心逻辑基于 MountFS + mountpoint inode/dentry 对象关系操作,而不是基于 MountPath 字符串做查找和前缀匹配。
MountPath 字符串可以继续用于展示、调试和用户态接口输出,但不应作为核心 mount 拓扑的一致性来源。