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