vhost_user_fs: Add support for CopyFileRange

Add support for the CopyFileRange request, introduced in FUSE 7.28.

Signed-off-by: Sergio Lopez <slp@redhat.com>
This commit is contained in:
Sergio Lopez
2020-03-20 14:08:26 +01:00
committed by Rob Bradford
parent b8cfdab8b6
commit 97e2d5d266
4 changed files with 121 additions and 0 deletions

View File

@@ -4,6 +4,7 @@
use std::collections::btree_map;
use std::collections::BTreeMap;
use std::convert::TryInto;
use std::ffi::{CStr, CString};
use std::fs::File;
use std::io;
@@ -1644,4 +1645,59 @@ impl FileSystem for PassthroughFs {
Ok(res as u64)
}
}
fn copyfilerange(
&self,
_ctx: Context,
inode_in: Inode,
handle_in: Handle,
offset_in: u64,
inode_out: Inode,
handle_out: Handle,
offset_out: u64,
len: u64,
flags: u64,
) -> io::Result<usize> {
let data_in = self
.handles
.read()
.unwrap()
.get(&handle_in)
.filter(|hd| hd.inode == inode_in)
.map(Arc::clone)
.ok_or_else(ebadf)?;
// Take just a read lock as we're not going to alter the file descriptor offset.
let fd_in = data_in.file.read().unwrap().as_raw_fd();
let data_out = self
.handles
.read()
.unwrap()
.get(&handle_out)
.filter(|hd| hd.inode == inode_out)
.map(Arc::clone)
.ok_or_else(ebadf)?;
// Take just a read lock as we're not going to alter the file descriptor offset.
let fd_out = data_out.file.read().unwrap().as_raw_fd();
// Safe because this will only modify `offset_in` and `offset_out` and we check
// the return value.
let res = unsafe {
libc::copy_file_range(
fd_in,
&mut (offset_in as i64) as &mut _ as *mut _,
fd_out,
&mut (offset_out as i64) as &mut _ as *mut _,
len.try_into().unwrap(),
flags.try_into().unwrap(),
)
};
if res < 0 {
Err(io::Error::last_os_error())
} else {
Ok(res as usize)
}
}
}