mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2025-02-22 11:22:26 +00:00
vhost_user_fs: Implement support for FUSE_LSEEK
Implement missing support for FUSE_LSEEK, which basically implies calling to libc::lseek on the file handle. As this operation alters the file offset, we take a write lock on the File's RwLock. Signed-off-by: Sergio Lopez <slp@redhat.com>
This commit is contained in:
parent
5aa9abca5e
commit
c821e96e2a
@ -1084,6 +1084,18 @@ pub trait FileSystem {
|
||||
Err(io::Error::from_raw_os_error(libc::ENOSYS))
|
||||
}
|
||||
|
||||
/// Reposition read/write file offset.
|
||||
fn lseek(
|
||||
&self,
|
||||
ctx: Context,
|
||||
inode: Self::Inode,
|
||||
handle: Self::Handle,
|
||||
offset: u64,
|
||||
whence: u32,
|
||||
) -> io::Result<u64> {
|
||||
Err(io::Error::from_raw_os_error(libc::ENOSYS))
|
||||
}
|
||||
|
||||
/// TODO: support this
|
||||
fn getlk(&self) -> io::Result<()> {
|
||||
Err(io::Error::from_raw_os_error(libc::ENOSYS))
|
||||
@ -1118,9 +1130,4 @@ pub trait FileSystem {
|
||||
fn notify_reply(&self) -> io::Result<()> {
|
||||
Err(io::Error::from_raw_os_error(libc::ENOSYS))
|
||||
}
|
||||
|
||||
/// TODO: support this
|
||||
fn lseek(&self) -> io::Result<()> {
|
||||
Err(io::Error::from_raw_os_error(libc::ENOSYS))
|
||||
}
|
||||
}
|
||||
|
@ -1616,4 +1616,32 @@ impl FileSystem for PassthroughFs {
|
||||
Err(io::Error::last_os_error())
|
||||
}
|
||||
}
|
||||
|
||||
fn lseek(
|
||||
&self,
|
||||
_ctx: Context,
|
||||
inode: Inode,
|
||||
handle: Handle,
|
||||
offset: u64,
|
||||
whence: u32,
|
||||
) -> io::Result<u64> {
|
||||
let data = self
|
||||
.handles
|
||||
.read()
|
||||
.unwrap()
|
||||
.get(&handle)
|
||||
.filter(|hd| hd.inode == inode)
|
||||
.map(Arc::clone)
|
||||
.ok_or_else(ebadf)?;
|
||||
|
||||
let fd = data.file.write().unwrap().as_raw_fd();
|
||||
|
||||
// Safe because this doesn't modify any memory and we check the return value.
|
||||
let res = unsafe { libc::lseek(fd, offset as libc::off64_t, whence as libc::c_int) };
|
||||
if res < 0 {
|
||||
Err(io::Error::last_os_error())
|
||||
} else {
|
||||
Ok(res as u64)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1241,11 +1241,24 @@ impl<F: FileSystem + Sync> Server<F> {
|
||||
}
|
||||
}
|
||||
|
||||
fn lseek(&self, in_header: InHeader, mut _r: Reader, w: Writer) -> Result<usize> {
|
||||
if let Err(e) = self.fs.lseek() {
|
||||
reply_error(e, in_header.unique, w)
|
||||
} else {
|
||||
Ok(0)
|
||||
fn lseek(&self, in_header: InHeader, mut r: Reader, w: Writer) -> Result<usize> {
|
||||
let LseekIn {
|
||||
fh, offset, whence, ..
|
||||
} = r.read_obj().map_err(Error::DecodeMessage)?;
|
||||
|
||||
match self.fs.lseek(
|
||||
Context::from(in_header),
|
||||
in_header.nodeid.into(),
|
||||
fh.into(),
|
||||
offset,
|
||||
whence,
|
||||
) {
|
||||
Ok(offset) => {
|
||||
let out = LseekOut { offset };
|
||||
|
||||
reply_ok(Some(out), None, in_header.unique, w)
|
||||
}
|
||||
Err(e) => reply_error(e, in_header.unique, w),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user