路径解析、打开与元数据操作
1. namei.c
namei 把用户路径字符串解析为 struct path。nameidata 保存当前位置、root、flags、符号链接栈和 RCU 状态。
主链:
1 | filename_lookup/path_parentat |
2. RCU-walk 与 ref-walk
RCU-walk 不对每个 dentry/mount 获取常规引用,使用 sequence counter 检测 rename/mount 变化,适合 dcache 热命中。遇到:
- cache miss;
- filesystem revalidate 需阻塞;
- 权限或 automount;
- 复杂 symlink;
- sequence 不稳定,
会 unlazy_walk() 转为 ref-walk。
3. open
1 | openat/openat2 |
openat2 的 RESOLVE_* 可限制 symlink、mount crossing、beneath/in-root,适合安全沙箱,不能用字符串前缀检查替代。
4. 创建与删除
vfs_create()/vfs_mkdir()vfs_unlink()/vfs_rmdir()vfs_link()/vfs_symlink()vfs_mknod()vfs_rename()
VFS 先做 mount read-only、权限、LSM、sticky bit、delegation 等检查,再调用目标目录 inode_operations。
5. rename
rename 是路径并发最复杂操作之一:
- 锁父目录 inode;
- 防止目录环;
- 处理 exchange/noreplace/whiteout;
- 更新 dcache;
- 调 filesystem transaction;
- 触发 fsnotify。
跨 superblock rename 返回 EXDEV。用户态需 copy+fsync+unlink 才能跨文件系统移动,但这不具备单步原子性。
6. 符号链接和 mount crossing
path walk 同时处理:
- absolute/relative path;
.、..;- symlink depth;
- bind mount 和 mountpoint;
- chroot/root;
- automount;
- managed dentry。
容器安全依赖 mount namespace 和 openat2 约束,而不仅是 realpath()。
7. 权限与 credential
检查基于调用时 credential、inode mode/ACL、mount flags、idmapped mount、LSM。打开后的 file->f_cred 保存 open 时凭据,后续某些操作不简单使用当前线程新凭据。
8. 性能
路径热点主要受:
- dcache/inode cache 命中;
- 目录索引实现;
- negative dentry;
- LSM/ACL;
- 网络文件系统 revalidate;
- rename 和目录锁竞争;
- 冷缓存存储延迟。
drop_caches 会破坏正常缓存,不应作为性能优化。
正在加载留言…