Doing a zero-copy move of data from a Linux kernel buffer to hard disk
am trying to move data from a buffer in kernel space into the hard disk without having to incur any additional copies from kernel buffer to user buffers or any oth开发者_StackOverflow社区er kernel buffers. Any ideas/suggestions would be most helpful.
The use case is basically a demux driver which collects data into a demux buffer in kernel space and this buffer has to be emptied periodically by copying the contents into a FUSE-based partition on the disk. As the buffer gets full, a user process is signalled which then determines the sector numbers on the disk the contents need to be copied to.
I was hoping to mmap the above demux kernel buffer into user address space and issue a write system call to the raw partition device. But from what I can see, the this data is being cached by the kernel on its way to the Hard Disk driver. And so I am assuming that involves additional copies by the linux kernel.
At this point I am wondering if there is any other mechansim to do this without involving additional copies by the kernel. I realize this is an unsual usage scenario for non-embedded environments, but I would appreciate any feedback on possible options.
BTW - I have tried using O_DIRECT when opening the raw partition, but the subsequent write call fails if the buffer being passed is the mmapped buffer.
Thanx!
You need to expose your demux buffer as a file descriptor (presumably, if you're using mmap()
then you're already doing this - great!).
On the kernel side, you then need to implement the splice_read
member of struct file_operations
.
On the userspace side, create a pipe()
, then use splice()
twice - once to move the data from the demux file descriptor into the pipe, and a second time to move the data from the pipe to the disk file. Use the SPLICE_F_MOVE
flag.
As documented in the splice()
man page, it will avoid actual copies where it can, by copying references to pages of kernel memory rather than the pages themselves.
精彩评论