文件描述符、读写与零拷贝
1. FD table
进程 files_struct 指向可扩展 fdtable:
- open bitmap;
- close-on-exec bitmap;
file **fd。
查找常用 RCU,更新在 file_lock 下。dup 共享同一 file,因此共享 f_pos 和 file status flags;独立 open 创建不同 file。
2. read/write
1 | ksys_read/ksys_write |
iov_iter 统一 user iovec、kernel vector、pipe、bvec、xarray 等数据源/目的地。
3. pread/pwrite 与 vectored I/O
pread/pwrite使用显式 offset,不修改共享f_pos;readv/writev使用多 iovec;preadv2/pwritev2支持 NOWAIT、DSYNC、HIPRI、APPEND 等 flags,具体支持依文件系统。
4. pipe
pipe.c 使用环形 pipe_buffer:
- anonymous pipe 与 FIFO 共用主体;
- reader/writer wait queue;
- 每 buffer 由
pipe_buf_operations管理 release/try_steal/get; - pipe size 可由 fcntl 调整并受系统/用户限制。
5. splice
splice.c 在 file、pipe、socket 间搬运 page/folio 引用,减少用户态往返复制:
1 | file -> splice_read -> pipe buffers -> splice_write -> target |
“零拷贝”不保证 NIC/块设备或所有 filesystem 完全不复制;fallback 和 checksum/加密都可能产生复制。
6. copy_file_range/remap
copy_file_range()允许文件系统高效复制;remap_file_range()可由 CoW 文件系统 reflink extent;- 不支持时可能 fallback 或返回错误;
- 跨文件系统语义和限制依内核版本。
7. seek
llseek 修改 f_pos;SEEK_DATA/SEEK_HOLE 由文件系统解释。稀疏文件复制工具应使用该接口但也要处理不支持情况。
8. fsync
vfs_fsync_range() 调 file_operations->fsync。正确持久化通常要求:
- 写文件数据;
fsync(file);- 创建/rename/unlink 后按需要
fsync(parent directory); - 底层设备正确实现 flush/FUA。
close 成功不等同于断电持久。
9. 限制与安全
MAX_RW_COUNT限制单次 I/O;- access mode 和 mandatory checks;
- LSM hooks;
- append-only/immutable;
- RLIMIT_FSIZE 和 signal;
- freeze/read-only;
- user pointer fault。
正在加载留言…