文件描述符、读写与零拷贝

文件描述符、读写与零拷贝

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
2
3
4
5
6
7
ksys_read/ksys_write
-> fdget_pos()
-> vfs_read/vfs_write
-> rw_verify_area()
-> new_sync_read/new_sync_write
-> call_read_iter/call_write_iter
-> filesystem file_operations

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_posSEEK_DATA/SEEK_HOLE 由文件系统解释。稀疏文件复制工具应使用该接口但也要处理不支持情况。

8. fsync

vfs_fsync_range()file_operations->fsync。正确持久化通常要求:

  1. 写文件数据;
  2. fsync(file)
  3. 创建/rename/unlink 后按需要 fsync(parent directory)
  4. 底层设备正确实现 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。

文章互动

阅读 --

留言

0 条留言

正在加载留言…