据我了解,传统上,Linux 内核对于添加新的系统调用持保守态度。
但是,我已经了解了 的存在copy_file_range
,它似乎与 做完全相同的事情sendfile
。我能发现的唯一区别是:
- 根本不适用于套接字,仅适用于正确的常规文件
- 允许设置输入和输出偏移
但对于常规文件, aseek
可能会实现相同的偏移语义,所以现在我很困惑系统调用的目的copy_file_range
是什么,如果它的功能是 San 现有系统调用的严格子集?特别是因为作为单独的事情进行查找可以非常明智地单独完成,因此不要进一步延长在内核空间中花费的时间。 (通常,操作系统设计的目标是使操作系统调用不被阻塞,并且在控制权已经交还给用户态的同时可以完成物理查找。)
答案1
copy_file_range
的优势在于sendfile
(并且splice
在于,在某些情况下,它实现了复制卸载。事实上这就是它的主要目的,它来自于长期的工作副本卸载时- 目的是提供对允许将块副本委托给硬件的功能的访问(例如SAN)。那份工作是仍在进行中;目前,副本卸载依赖于文件系统支持,其中副本可以由文件系统中的引用替换,也可以委托给服务器。 (看目录写时复制?了解详情。)
sendfile
另一方面来自于高效地将文件发送到网络的愿望;同样,splice
可以有效地将文件发送到管道。sendfile
很久以前就被扩展为将文件发送到其他文件(splice
在后台使用),但假设仍然是优化的读写:进程可以询问内核,而不是在用户空间中读取数据并写入数据处理读写循环。
我怀疑 的copy_file_range
存在与额外的输出偏移量参数有关:如果您考虑公开硬件中可用的低级卸载块复制功能,则将其与基于文件描述符的 API 联系起来需要两个偏移量;虽然可以使用sendfile
并且无论输出文件描述符上的当前偏移量是什么,但对于复制卸载目标而言,这可能不够紧密耦合。
(通用的copy_file_range
实现,在没有特定支持的文件系统上使用,代表splice
in同样的方式sendfile
。可以说sendfile
可以在可能的情况下使用copy_file_range
,我不知道这是否已经实现。)