mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
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:
committed by
Rob Bradford
parent
b8cfdab8b6
commit
97e2d5d266
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user