从最小 FUSE 复现到 nydusd umount 修复:一次挂载点失效通知没有发到正确位置的问题
太长不看版
- 在
nydusd的这个问题里,现象是:第一次挂载后,一个路径比如/a/b/c还能正常访问;经历一次 unmount / remount 以后,再去访问它会提示“这个路径不存在”;但如果先对它的父目录做一次ls -l /a/b,再回头访问/a/b/c,它又好了。 - 原因是:
nydusd umount时,那条挂载点入口的失效通知没有发到正确的“直接父目录 inode + 单个 entry name”上,内核于是还沿用了旧的名字状态。后面ls -l之所以能把它救回来,是因为它会继续触发更强的父目录读取和子项属性访问,把当前的名字和对象关系重新交回内核。 - 修复点是:
nydusd不要把整条挂载路径当成一个名字去发失效通知,而是要对挂载点最后一级名字,按它的直接父目录 inode 和 basename 去发。
这篇文章先不从具体系统讲起,而是先整理一个很绕的路径问题。
如果第一次读到 FUSE,可以先把它理解成:文件系统逻辑主要跑在用户态,内核通过一套接口和它配合。
前四节先只讲这个 bug 本身、FUSE 背景和一个最小 demo,不急着抛真实系统名字。到第 5 节,再回到真实场景,看它为什么会落到 nydusd 的那段修复上。