土法炼钢兴趣小组的算法知识备份

【操作系统百科】路径名解析

文章导航

分类入口
os
标签入口
#namei#lookup-rcu#openat2#symlink#pathname

目录

用户传一个字符串 /usr/bin/ls,内核要一级一级查 dcache / 磁盘,穿越 mount 点、symlink,最终拿到目标 inode。这个过程叫 namei(name-to-inode),是 VFS 最频繁的操作。

一、先看图

flowchart LR
    PATH["/usr/bin/ls"] --> SLASH[/ → root dentry]
    SLASH --> USR[lookup "usr"]
    USR --> BIN[lookup "bin"]
    BIN -->|mount 穿越| BINMNT[/usr/bin 挂载点]
    BINMNT --> LS[lookup "ls"]
    LS --> INODE[inode 返回]
    classDef step fill:#388bfd22,stroke:#388bfd,color:#adbac7;
    classDef mount fill:#a371f722,stroke:#a371f7,color:#adbac7;
    class SLASH,USR,BIN,LS,INODE step
    class BINMNT mount

二、三阶段查找

2.1 LOOKUP_RCU(快速路径)

不加任何锁,RCU 保护:

  1. 从根 dentry 开始
  2. 每个组件用 d_hash 查 dcache
  3. 验证 d_seq(dentry 序列号)保证数据一致
  4. mount 穿越用 mnt_seq 验证

成功率 >99%(热路径命中 dcache)。

2.2 LOOKUP_LOCK(降级)

RCU 验证失败 → 降级拿 inode->i_rwsem + dentry 引用。

2.3 LOOKUP_SLOW(磁盘)

dcache miss → 调用 inode->i_op->lookup() → 读磁盘目录。

三、mount 穿越

路径走到 mount 点时:

/        → root sb
/usr     → root sb
/usr/bin → 如果 /usr 是独立挂载,穿越到新 sb 的 root dentry

follow_managed() 处理 automount + mount 穿越。

遇到 symlink → 递归解析目标。

保护:

五、openat2 与 RESOLVE_*

openat2(2) 引入安全控制:

struct open_how how = {
    .flags = O_RDONLY,
    .resolve = RESOLVE_NO_SYMLINKS | RESOLVE_BENEATH,
};
int fd = openat2(dirfd, "path", &how, sizeof(how));

容器安全的基石。

六、AT_EMPTY_PATH 与 fstat 优化

openat(dirfd, "", AT_EMPTY_PATH)
// 等价于对 dirfd 本身操作

配合 /proc/self/fd/N → 可以用路径操作已打开的 fd。

七、case-insensitive

ext4 5.2+ 支持 casefold 特性(UTF-8 case folding):

mkfs.ext4 -O casefold /dev/sda1
chattr +F /mnt/mydir    # 该目录及子目录大小写不敏感

内核在 lookup 时用 UTF-8 NFC 正规化 + case fold 比较。

限制:不同 locale 的 case mapping 不同;不支持 Turkic “i” 问题。

八、RENAME_EXCHANGE

renameat2(olddirfd, "a", newdirfd, "b", RENAME_EXCHANGE);
// 原子交换 a 和 b

比 rename+rename 安全——不会出现中间状态。

RENAME_NOREPLACE:不覆盖目标(原子 create-or-fail)。

九、dcache 调优

# 当前 dcache 状态
cat /proc/sys/fs/dentry-state

# negative dentry 限制(6.1+)
sysctl fs.negative-dentry-limit=0    # 不限(默认)

大量 negative dentry 场景:编译器频繁探测不存在的头文件 → dcache 膨胀。

十、路径查找性能

# 衡量 lookup 速度
perf stat -e 'syscalls:sys_enter_openat' -- find /usr -name '*.so' > /dev/null

# dcache 命中率
perf stat -e dentry-cache-misses,dentry-cache-accesses 2>/dev/null
# 或看 /proc/slabinfo dentry 变化

十一、小结


参考文献

工具


上一篇VFS 四层抽象 下一篇fd 表与 struct file

同主题继续阅读

把当前热点继续串成多页阅读,而不是停在单篇消费。

2026-04-27 · os

【操作系统百科】内存回收

Linux 内存回收是 VM 最复杂的子系统之一。本文讲 active/inactive LRU、kswapd 与 direct reclaim、watermark 三线、swappiness 的真实含义、MGLRU 改造、memcg 回收与 PSI。

2026-04-28 · os

【操作系统百科】交换

swap 还值得开吗?本文讲 swap area 基础、swap cache、zram 压缩内存、zswap 前端压缩池、swappiness 的真实含义、容器里的 swap 策略,以及为什么现代 Android 全靠 zram 不靠磁盘。

2026-05-03 · os

【操作系统百科】Slab/SLUB 分配器

buddy 只管页粒度(4K+),内核大多数对象只有几十到几百字节。slab/SLUB 在 buddy 之上做对象级缓存。本文讲 slab 历史、SLUB 接手、SLOB 退场、kmem_cache、per-CPU cache、KASAN 集成。

2026-05-07 · os

【操作系统百科】用户态分配器

glibc malloc、tcmalloc、jemalloc、mimalloc 各有哲学。本文讲 arena、thread cache、size class、madvise 返还策略、碎片与 RSS 膨胀、如何根据负载选分配器。


By .