首页/目录/全部文章

全部文章

八个专题的源码、算法与协议笔记都在这里。

笔记列表

页缓存、写回与块 I/O

页缓存、写回与块 I/O

1. address_space

inode 的 i_mapping 连接文件 offset 与 page-cache folio。核心:

  • i_pages:XArray;
  • a_ops:文件系统 I/O 回调;
  • host:inode;
  • writeback/error 状态。

页缓存核心实现主要在 mm/filemap.cfs/ 提供文件系统和 writeback 对接。

2. Buffered read

1
2
3
4
5
6
read_iter
-> filemap_read()
-> lookup folio in mapping
-> hit: copy to iov_iter
-> miss: readahead / a_ops->read_folio
-> wait folio uptodate

readahead 根据顺序访问动态扩大窗口。随机负载过大预读会浪费 I/O 和 cache。

3. Buffered write

1
2
3
4
5
6
generic_file_write_iter
-> generic_perform_write
-> a_ops->write_begin
-> copy from user
-> a_ops->write_end
-> folio_mark_dirty

write 返回通常只表示数据进入页缓存。脏页由 balance_dirty_pages 限流,并由 writeback worker 或 fsync 下发。

4. fs-writeback.c

writeback 以 backing_dev_info / writeback domain 组织:

  • 周期写回;
  • 超过 dirty threshold;
  • 内存回收;
  • fsync/sync;
  • filesystem sync/freeze。

writeback_single_inode() 协调 inode state 和 address_space_operations->writepages。inode dirty 类型区分数据、元数据、时间戳等。

5. Buffer head

buffer.cbuffer_head 表示 page 中一段块及状态,提供:

  • buffer cache helpers;
  • submit_bh()
  • block mapping;
  • metadata I/O;
  • sync_mapping_buffers()

它是传统接口,ext4 等仍大量用于 metadata;新文件系统数据路径更多使用 iomap/bio/folio。

6. Mpage

mpage.c 为简单 block mapping 文件系统聚合连续块 I/O,减少逐 buffer 提交。复杂 extent、压缩、CoW 文件系统通常有自己的路径。

7. 错误传播

异步 writeback error 记录在 mapping errseq。后续 fsync 和某些 write 路径通过 file_check_and_advance_wb_err() 向每个 file 报告,避免错误静默丢失。

应用必须检查 write、fsync 和 close(部分错误)返回值。

8. 回收关系

clean file folio 可直接丢弃;dirty folio 需写回;正在 writeback 的 folio可能造成 reclaim stall。内存、存储延迟和脏页阈值相互影响:

1
2
slow device -> writeback backlog -> dirty throttling
-> application latency -> reclaim pressure

9. 观测

1
2
3
4
cat /proc/meminfo | grep -E 'Cached|Dirty|Writeback'
cat /proc/vmstat | grep -E 'dirty|writeback|pgpg'
cat /proc/pressure/io
cat /proc/diskstats

调整 dirty 参数前应先确定设备写延迟和 filesystem journal 状态。

权限、ACL、Xattr、文件锁与配额

权限、ACL、Xattr、文件锁与配额

1. 权限

VFS permission 综合:

  • inode mode uid/gid;
  • POSIX ACL;
  • capability;
  • mount flags(noexec/nodev/nosuid/read-only);
  • idmapped mount;
  • immutable/append flags;
  • LSM hooks;
  • filesystem-specific policy。

inode_permission() 是核心入口之一,具体文件系统可实现 permission

2. 属性修改

attr.cnotify_change() 处理 chmod/chown/truncate/time:

  1. setattr_prepare() 通用校验;
  2. security hook;
  3. filesystem setattr()
  4. setattr_copy() 更新通用字段;
  5. mark inode dirty/notify。

truncate 还需处理 page cache、DIO、extent 和日志顺序。

3. Xattr

xattr.c 提供 get/set/list/remove。namespace:

  • user.*
  • trusted.*
  • security.*
  • system.*

具体文件系统通过 xattr_handler 存取。SELinux label、capability、ACL 都可依赖 xattr;挂载/复制工具忽略 xattr 会改变安全语义。

4. POSIX ACL

posix_acl.c

  • 解析和校验 ACL;
  • 计算 mode 与 mask;
  • permission check;
  • inheritance/default ACL。

CONFIG_FS_POSIX_ACL 只提供公共 helper,具体文件系统还需启用自身 ACL 支持。

5. 文件锁

locks.c 实现:

  • POSIX record lock;
  • BSD flock
  • lease;
  • OFD lock;
  • lock manager hooks。

advisory lock 只约束配合者;网络文件系统还涉及远端 lock protocol、grace period 和故障恢复。

6. Lease/delegation

lease 可在他人打开冲突模式时通知 owner;NFS delegation 与 VFS break lease 机制交互。open/unlink/rename 可能返回 delegation,调用者需 break 后重试。

7. Quota

quota/ 支持:

  • user quota;
  • group quota;
  • project quota;
  • quota format;
  • dquot cache/charge;
  • quota netlink warning。

quota 与 memcg 不同:前者限制持久存储 block/inode,后者限制内存。

8. 安全边界

  • TOCTOU:权限检查应与实际 inode/path 操作在 VFS 内完成;
  • 不用用户态 access() 结果代替 open()
  • privileged helper 使用 openat2 和 dirfd;
  • xattr 名称/长度需严格验证;
  • idmapped mount 下 uid/gid 比较使用映射 helper;
  • 网络文件系统缓存权限需考虑 server revalidation。

9. 排障

1
2
3
4
5
6
namei -l /path
getfacl /path
getfattr -d -m- /path
lsattr /path
lslocks
quota -vs

事件通知与异步 I/O 接口

事件通知与异步 I/O 接口

1. poll/select

select.c 实现 select/poll 公共扫描。文件 poll 回调通过 poll_wait() 把当前任务挂到 wait queue,返回 readiness mask。事件到来后 wakeup,再次调用驱动/文件系统确认状态。

2. epoll

eventpoll.c 维护 interest rbtree 和 ready list:

  • epoll_ctl() 添加/修改/删除 file;
  • callback 在目标 wait queue 唤醒时把 epitem 加 ready;
  • epoll_wait() 取事件;
  • 支持 level/edge、oneshot、exclusive。

edge-triggered 应配合 nonblocking 并读到 EAGAIN,否则可能永久等待。

3. eventfd/signalfd/timerfd

  • eventfd.c:64 位计数器,可作为内核/用户态事件桥;
  • signalfd.c:把 signal queue 暴露为可读 fd;
  • timerfd.c:hrtimer/alarm 到 fd;
  • 均可被 epoll 统一监控。

4. AIO

aio.c 是传统 Linux native AIO,建立 aio context、iocb、completion ring。它不同于 POSIX thread AIO,也不同于 io_uring。文件系统是否真正异步依赖 read_iter/write_iter 与 direct I/O 路径。

io_uring 主实现位于源码树 io_uring/,不是 fs/ 子目录;但大量操作最终调用 VFS。

5. fsnotify

notify/ 公共层连接 inode/mount 事件与 group/mark:

1
2
3
4
5
VFS operation
-> fsnotify_* hook
-> match inode/mount marks
-> group event queue
-> inotify/fanotify userspace read

6. inotify/dnotify/fanotify

  • dnotify:旧 fcntl 目录通知;
  • inotify:按 path/inode watch,适合应用;
  • fanotify:更强 mount/filesystem 监控和 permission event,适合安全软件。

rename 通常表现为带 cookie 的 moved_from/moved_to,但 queue overflow 会丢对应关系。

7. 一致性限制

通知不是完整审计日志:

  • queue 有上限;
  • overflow 后需全量 rescan;
  • watch inode,不等于路径永久稳定;
  • unlink 后 open fd 仍可访问;
  • remote filesystem 事件能力依实现;
  • mmap 写入不一定产生应用预期的逐次事件。

8. userfaultfd

fs/userfaultfd.c 提供 fd、ioctl、poll 和消息队列;真正缺页处理和 PTE 操作与 mm/userfaultfd.cmm/memory.c 协作。它可用于 missing/minor/write-protect fault,权限受 sysctl、capability 和 feature 限制。

9. 并发与生命周期

epoll、fsnotify 等都持有 file/inode/group 引用并注册 callback。close、unmount、watch removal 和事件到达可并发,代码依赖 RCU、spinlock、wait queue 和 SRCU。驱动 poll callback 不能睡眠于不允许的上下文。

Iomap、Direct I/O 与 DAX

Iomap、Direct I/O 与 DAX

1. Iomap

fs/iomap/struct iomap 描述文件逻辑范围到后端的映射:

  • mapped;
  • hole;
  • delalloc;
  • unwritten;
  • inline;
  • extent offset/length/address/flags。

文件系统实现 iomap_ops->iomap_begin/end,公共层实现 buffered I/O、direct I/O、seek、fiemap、swapfile 和 writeback helper。

2. Buffered iomap

iomap_file_buffered_write()

  1. 请求当前 extent iomap;
  2. 获取/创建 page-cache folio;
  3. 准备部分块;
  4. copy user data;
  5. mark dirty;
  6. iomap_end 提交文件系统状态。

XFS 等深度使用 iomap,ext4 部分路径也逐步采用。

3. Direct I/O

传统 direct-io.c 与 iomap DIO 均绕过 page cache 数据缓存:

1
2
3
4
5
6
read/write_iter IOCB_DIRECT
-> alignment/permission checks
-> filesystem map extent
-> pin user pages / build bio
-> submit block I/O
-> completion + inode size/error handling

Direct I/O 不是“无缓存”:设备、控制器仍有 cache,metadata 也可能缓存。

4. Buffered 与 DIO 一致性

同一范围混用必须处理:

  • flush/invalidate page cache;
  • wait writeback;
  • inode lock;
  • outstanding DIO (inode_dio_begin/end/wait);
  • truncate/punch hole;
  • unwritten extent conversion。

应用随意混用 buffered 和 O_DIRECT 可能产生性能抖动。

5. Alignment

O_DIRECT 的地址、长度、offset 约束依文件系统和设备 logical block。错误通常 EINVAL,不要硬编码 4 KiB;可查询 statx DIO alignment(若支持)或按设备/文件系统要求。

6. DAX

dax.c 让持久内存/内存型块设备绕过 page cache 和传统 block I/O,CPU 直接访问映射:

  • DAX fault 建立 PFN 映射;
  • iomap 获取物理 extent;
  • dax_iomap_rw 直接 copy/flush;
  • 与 truncate、reflink、GUP、memory failure 协同。

普通 eMMC/NVMe SSD 不等于 DAX 设备。RK3588 通常不使用 FS-DAX,除非平台有符合要求的内存型后端或特定 Rockchip ramdisk 配置。

7. 持久性

DAX 避免 page cache,但持久性仍要求:

  • 正确 cache line flush;
  • ordering/barrier;
  • filesystem transaction;
  • fsync/msync 语义;
  • 设备 persistence domain。

8. 性能选择

模式 优点 代价
buffered readahead、write coalescing、低对齐要求 双重缓存/回写延迟
direct 应用控制缓存、减少 page cache 污染 对齐、并发和小 I/O 成本
DAX 直接 load/store、无 page cache 硬件限制、fault/持久性复杂

应按真实 workload 测试,不能把 O_DIRECT 当作通用加速开关。

加密、完整性与文件系统安全

加密、完整性与文件系统安全

1. fscrypt

fs/crypto/ 为 ext4/f2fs/UBIFS 等提供文件级加密公共层:

  • policy 与 context;
  • keyring/key specifier;
  • filename encryption;
  • data bio crypto;
  • inline encryption;
  • key setup/eviction;
  • encrypted symlink。

文件系统负责存储 encryption context 并在 inode/dir 操作中调用 helper。

2. 名称和数据

fscrypt 通常分别派生:

  • file content key;
  • filename key;
  • inode nonce/context。

无 key 时仍可能枚举加密名称的编码形式,但不能透明访问明文。加密不自动隐藏目录结构、大小、时间等所有 metadata。

3. Inline crypto

支持 blk-crypto 的控制器可按 bio 使用硬件 inline encryption。是否启用取决于:

  • filesystem policy;
  • block device keyslot manager;
  • algorithm/data unit size;
  • 驱动和硬件;
  • fallback 配置。

RK3588 平台必须通过实际内核配置和控制器驱动确认,不能仅凭 SoC 加密模块存在推断。

4. fs-verity

fs/verity/ 为只读文件内容建立 Merkle tree,打开/读页时验证数据:

  • enable ioctl 构建 descriptor/tree;
  • digest 标识可信内容;
  • read path 验证数据块到 root hash;
  • 可结合 signature/keyring。

启用后文件内容不可再修改。fs-verity 是完整性,不是保密性。

5. 与 dm-verity 区别

机制 粒度
fs-verity 单文件
dm-verity 整个只读块设备映射
fscrypt 文件/目录内容加密
dm-crypt 块设备加密

产品可组合,但 key、更新和错误恢复策略不同。

6. VFS 安全钩子

open、permission、create、rename、xattr、mount、ioctl 等路径调用 LSM hooks。文件系统自身权限检查不能绕过 VFS/LSM;stacked/network fs 还要考虑 lower/server 权限。

7. Mount flags

  • nodev
  • nosuid
  • noexec
  • ro
  • nosymfollow(按本分支支持)

这些是纵深防御。noexec 不阻止解释器主动读取脚本,也不是内容信任机制。

8. 安全开发

  • 使用 openat2 防路径逃逸;
  • 不跟随不可信 symlink;
  • 校验 ioctl/xattr/fiemap 长度;
  • privileged copy 保留 ACL/xattr/ownership;
  • fs parser 使用类型化 spec;
  • 处理 idmapped mount;
  • 对 image mount 使用只读、nodev、nosuid、noexec 和隔离 namespace;
  • fuzz 测试不可信磁盘镜像解析器。

内存、伪文件系统与 Overlay/FUSE

内存、伪文件系统与 Overlay/FUSE

1. ramfs/tmpfs

ramfs/ 提供简单内存文件系统;tmpfs 数据实际由 MM shmem 实现,可:

  • 使用 page cache;
  • 在启用 swap 时换出;
  • 设置 size/nr_inodes;
  • 支持 seals、huge page policy(按配置);
  • 作为 /dev/shm、容器临时层。

ramfs 没有有效容量限制,特权用户写满可耗尽内存;生产更适合有限额 tmpfs。

2. procfs

proc/ 通过 seq_file 和 task/mm/net 等接口导出动态内核状态。/proc/<pid> 可受 pid namespace、hidepid、ptrace 权限限制。大量读取 proc 可能触发昂贵遍历,不是零成本。

3. kernfs/sysfs

kernfs 提供层次节点、active reference、open file 和 notify 基础;sysfs 把 kobject 属性映射为文件。

sysfs ABI 通常要求一个属性一个值,用户态不应依赖内部目录创建时序。store callback 必须严格解析长度和范围。

4. debugfs/tracefs/configfs

  • debugfs:调试接口,无稳定 ABI;
  • tracefs:tracing 专用;
  • configfs:用户 mkdir/write 创建内核对象;
  • pstore:持久化崩溃/固件日志。

生产镜像可不挂 debugfs;不能把安全敏感控制长期暴露给普通用户。

5. OverlayFS

OverlayFS 合并:

  • lower layers:只读或基础;
  • upper:可写;
  • workdir:原子操作辅助;
  • merged view。

写 lower 文件触发 copy-up;删除以 whiteout/opaque 表示;rename、xattr、hard link、metacopy/index 等影响语义和性能。

容器镜像小文件密集写会产生大量 copy-up 和 metadata I/O。

6. FUSE

FUSE 将 VFS 请求通过 /dev/fuse 发送给用户态 daemon:

1
2
VFS op -> fuse request queue -> userspace daemon
-> backend -> reply -> waiting task

内核维护 inode/dentry/attribute 缓存、background request、interrupt 和 DAX(virtio-fs 等按配置)。daemon 卡住会让调用进程阻塞。

7. devpts/anon inode

  • devpts 管理 pseudo terminal;
  • anon_inodefs 为 epoll/eventfd/io_uring 等没有真实路径的 file 提供 inode/file;
  • nsfs 把 namespace 对象暴露为 fd;
  • configfs/sysfs 与普通持久文件系统语义不同。

8. RK3588

  • 只读根常用 EROFS/SquashFS lower + tmpfs/ext4 upper;
  • 容器 overlay upper 放在慢 eMMC 时 metadata latency明显;
  • tmpfs size 应与 memcg 联合限制;
  • FUSE 额外 context switch 对小 I/O 明显;
  • debugfs/tracefs 仅排障时开放。

本地磁盘文件系统对比

本地磁盘文件系统对比

1. ext4

目录:fs/ext4/,日志:fs/jbd2/

特点:

  • extent tree;
  • block group/mballoc;
  • ordered/writeback/journal data mode;
  • delayed allocation;
  • metadata checksum;
  • fast commit;
  • fscrypt/fs-verity/quota;
  • 成熟、适合 eMMC/NVMe 通用场景。

已有逐模块文档见 ext4/

2. F2FS

面向 flash 的 segment/log-structured 设计:

  • NAT/SIT/SSA;
  • checkpoint;
  • node/data logs;
  • garbage collection;
  • SSR/LFS;
  • compression、checkpoint disable 等可选功能。

适合写入模式和 flash 特性匹配的设备,但 GC、checkpoint 和空间预留会影响尾延迟。

3. XFS

特点:

  • allocation group 并行;
  • B+tree metadata;
  • delayed logging/CIL;
  • iomap;
  • reflink/rmap/refcount;
  • online scrub/repair 部分能力;
  • 大文件、大容量和并发。

小容量 eMMC 并不天然受益,需考虑内存和运维工具。

4. Btrfs

CoW tree 架构:

  • metadata/data checksum;
  • snapshot/subvolume;
  • reflink;
  • compression;
  • multi-device/RAID;
  • scrub;
  • delayed refs/extent tree。

功能丰富但写放大、fragmentation、ENOSPC 语义和恢复运维更复杂。

5. 一致性模型

文件系统 主要恢复机制
ext4 JBD2 metadata journal/fast commit
F2FS checkpoint + roll-forward
XFS metadata log
Btrfs CoW transaction + tree log

“有日志”不代表最近应用数据一定持久;应用仍需 fsync 和正确 rename protocol。

6. 选择建议

场景 常见选择
通用系统盘/eMMC ext4
高频 flash 写、已充分验证 F2FS
NVMe 大文件/并发 ext4 或 XFS
snapshot/checksum/compression Btrfs
极简无日志 ext2(需接受恢复风险)

最终选择应基于掉电测试、空间占用、升级恢复工具、写放大和 p99,不仅是峰值带宽。

7. 通用调用边界

四者都通过 VFS ops 接入,但内部 extent、日志和 writeback 完全不同。不能把 ext4 mount option 或 fsck 工具用于其他文件系统。

8. RK3588 验证

  • eMMC cache/flush 是否正确;
  • 供电掉电窗口;
  • NVMe thermal throttle;
  • discard 策略;
  • journal/checkpoint latency;
  • 多媒体大文件删除/循环覆盖;
  • inode 和空间耗尽;
  • 内核与用户态修复工具版本匹配。

只读与闪存文件系统

只读与闪存文件系统

1. EROFS

erofs/ 面向只读镜像:

  • compact inode;
  • chunk/flat block mapping;
  • inline tail;
  • LZ4/LZMA 等压缩(按配置);
  • page cache 和 readmore;
  • fscache 模式(按分支能力);
  • 适合 Android/rootfs/container image。

强调随机读和较低 metadata 开销。

2. SquashFS

squashfs/ 以 block 压缩:

  • metadata/data/fragment table;
  • 多种 compressor;
  • read-only;
  • image 构建时确定 block size;
  • 常用于固件 rootfs。

较大压缩块提高压缩率和顺序吞吐,但随机读解压放大更大。

3. CramFS/RomFS

更简单、功能有限的只读格式,适合兼容或极简场景。新产品通常优先评估 EROFS/SquashFS。

4. UBIFS

ubifs/ 工作在 UBI volume 上,不直接面向普通块设备:

1
raw NAND -> MTD -> UBI -> UBIFS

特点:

  • journal;
  • tree node;
  • LEB/PEB 抽象;
  • wear leveling 由 UBI;
  • compression;
  • budgeting;
  • orphan/recovery。

5. JFFS2

直接面向 MTD,节点日志和 GC。小 flash 可用,但大容量 mount scan、内存和 GC 成本可能明显。

6. eMMC 与 raw NAND

  • eMMC/UFS/SD/NVMe 是块设备,通常 ext4/F2FS/EROFS/SquashFS;
  • raw NAND 需要坏块和磨损管理,通常 UBI/UBIFS;
  • 不要在 raw NAND 上直接使用假设可靠块设备的 ext4;
  • 不要把 UBIFS 镜像挂到普通 block device。

7. Overlay 组合

只读 lower + 可写 upper:

1
2
3
EROFS/SquashFS lower
+ ext4/F2FS/tmpfs upper
-> OverlayFS merged root

升级可替换 lower image,但必须设计 upper schema migration、whiteout 和回滚。

8. RK3588 调优

  • 根据 Cortex-A76/A55 CPU 与存储带宽选择压缩算法;
  • 测量冷启动、随机 fault、顺序读和 CPU;
  • 多媒体文件通常已压缩,再压缩收益低;
  • image block size 与访问粒度匹配;
  • 验证 dm-verity/fs-verity;
  • A/B 更新做断电测试。

9. 观测

1
2
3
4
5
findmnt -o SOURCE,TARGET,FSTYPE,OPTIONS
cat /sys/class/mtd/mtd*/name
ubinfo -a
cat /proc/meminfo
cat /proc/pressure/io

网络与分布式文件系统

网络与分布式文件系统

1. 共性

网络文件系统把 VFS 操作转换为远端协议:

1
2
3
4
VFS path/file/inode ops
-> client cache + consistency policy
-> RPC/message transport
-> remote server/storage

本地 dentry/inode/page cache 与远端权威状态之间必须 revalidate。

2. NFS

nfs/ + net/sunrpc/

  • NFSv2/v3/v4;
  • RPC transport;
  • attribute/data cache;
  • open/lock/stateid;
  • delegation;
  • pNFS;
  • idmapping/security flavor;
  • fscache。

NFSv4 是 stateful,server reboot 需要 lease/grace recovery。

3. SMB/CIFS

smb/client/

  • SMB2/3 session/tree/file;
  • credits;
  • lease/oplock;
  • signing/encryption;
  • multichannel(按配置);
  • durable handle;
  • DFS;
  • fscache。

smb/server/ 为 ksmbd server。client 与 server 代码和安全边界不同。

4. CephFS

fs/ceph/ 实现:

  • MDS client/session;
  • inode/dentry/cap/lease;
  • metadata request;
  • snapshots/quotas;
  • page cache/writeback。

公共 MON/OSD/messenger/CRUSH 位于 net/ceph/。CephFS metadata 走 MDS,file data 主要走 OSD。

5. 9P/AFS/其他

  • 9P:常用于 virtio/container/VM host sharing;
  • AFS:cell/volume/callback;
  • Coda/OrangeFS:各自分布式模型。

具体缓存、一致性和断线语义不可互换。

6. FSCACHE/CacheFiles

netfs/fscache/ 为支持的网络文件系统提供本地缓存编排,cachefiles/ 用本地目录作为后端。缓存可减少重复下载,但不会把网络 fs 变成本地强一致文件系统。

7. 错误语义

网络故障可能产生:

  • timeout/retransmit;
  • stale file handle;
  • lease/delegation recall;
  • session reconnect;
  • server not responding;
  • permission/id mapping mismatch;
  • uncertain completion。

应用需区分可重试读与非幂等元数据操作。

8. 性能

  • RTT 主导小文件 metadata;
  • 大文件受带宽、request size、并发和服务端存储限制;
  • attribute cache 降低 RTT 但增加陈旧窗口;
  • page cache/writeback 可能延迟错误;
  • 网络丢包会放大尾延迟;
  • fscache 受本地盘性能影响。

9. RK3588

边缘设备优先确认:

  • 稳定时间同步和 DNS;
  • MTU/丢包/TCP;
  • credential/keyring;
  • 断网恢复;
  • shutdown 时 writeback;
  • memcg 下 page cache;
  • 网络文件系统不可用时业务降级。

并发、缓存一致性与故障恢复

并发、缓存一致性与故障恢复

1. 锁层次

VFS 常见锁:

保护
s_umount super freeze/unmount
mount lock/seqlock mount topology
i_rwsem inode/目录操作
i_lock inode state/flags/lists
d_lock dentry fields
rename lock rename/pathwalk sequence
file_lock fdtable update
folio lock page cache folio state
mapping xarray lock page cache index

具体文件系统还有 transaction、extent、allocation group、journal、log 等锁。

2. Lockless fast path

  • fd lookup 使用 RCU;
  • pathwalk 优先 RCU-walk;
  • dcache hash lookup 配合 sequence validation;
  • mount/path rename 通过 seqlock 检测变化。

无锁读取不是无同步,而是读取后验证;失败需重试或转慢路径。

3. Dentry/inode 一致性

本地 fs 通常由 VFS mutation 更新 dcache;网络/stacked fs 可能通过 d_revalidate 检查远端/lower 状态。negative dentry timeout 和 attribute cache 会影响“何时看到新文件”。

4. Data/metadata ordering

持久化涉及:

1
2
3
4
5
6
7
8
application data
-> page cache/DIO
-> filesystem allocation
-> journal/log/CoW transaction
-> bio
-> block layer
-> device volatile cache
-> media

文件系统只能在设备正确实现 flush/FUA 时兑现顺序。

5. fsync 语义

fsync 目标是该文件所需数据和 metadata;rename/create 的目录项持久性可能还需 parent fsync。不同文件系统的 journal/CoW 实现不同,但应用应使用通用 crash-safe protocol,而不依赖偶然行为。

6. Freeze/unmount

  • freeze 阻断新写并同步,供 snapshot;
  • unmount 先从 namespace detach,再等待/关闭 super;
  • lazy unmount 只断开可见路径,活动引用仍存在;
  • forced unmount 可能让后续 I/O 返回错误。

7. 崩溃恢复

  • journal replay;
  • log replay;
  • orphan cleanup;
  • checkpoint/roll-forward;
  • CoW tree root 选择;
  • fsck/offline repair;
  • online scrub。

恢复机制无法修复所有硬件 silent corruption;checksum、scrub 和备份仍必要。

8. Writeback error

异步错误可能在后续 fsync 才报告。多进程对同一 inode 打开的 file 各自跟踪 errseq,应用必须检查并记录第一次持久化错误。

9. Deadlock 防护

存储路径分配内存常使用 GFP_NOFS/memalloc_nofs,避免回收再次进入同一文件系统。新增代码不能在 filesystem transaction lock 下随意 GFP_KERNEL 分配或调用可递归 VFS 操作。

10. 测试

  • fsx/xfstests;
  • fault injection;
  • dm-flakey;
  • 强制掉电;
  • fsfreeze;
  • ENOSPC/inode exhaustion;
  • I/O error;
  • concurrent rename/unlink/mmap;
  • mount namespace stress。