Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion src/abi/fuse_abi_linux.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,11 @@ const INIT_EXT: u64 = 0x4000_0000;
// This flag indicates whether the guest kernel enable per-file dax
const PERFILE_DAX: u64 = 0x2_0000_0000;

// This flag indicates whether to enable fd-passthrough. It was defined in the
// Anolis kernel but not in the upstream kernel. To avoid collision, we'll set
// it to the most significant bit.
const FD_PASSTHROUGH: u64 = 0x8000_0000_0000_0000;

/**
*
* fuse_attr flags
Expand Down Expand Up @@ -442,6 +447,9 @@ bitflags! {
/// -. write has WRITE_KILL_PRIV
const HANDLE_KILLPRIV_V2 = HANDLE_KILLPRIV_V2;

/// Indicates the kernel support fuse fd passthrough.
const FD_PASSTHROUGH = FD_PASSTHROUGH;

/// The fuse_init_in is extended.
const INIT_EXT = INIT_EXT;

Expand Down Expand Up @@ -912,7 +920,7 @@ unsafe impl ByteValued for CreateIn {}
pub struct OpenOut {
pub fh: u64,
pub open_flags: u32,
pub padding: u32,
pub passthrough: u32,
}
unsafe impl ByteValued for OpenOut {}

Expand Down
2 changes: 1 addition & 1 deletion src/abi/fuse_abi_macos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -683,7 +683,7 @@ unsafe impl ByteValued for CreateIn {}
pub struct OpenOut {
pub fh: u64,
pub open_flags: u32,
pub padding: u32,
pub passthrough: u32,
}
unsafe impl ByteValued for OpenOut {}

Expand Down
11 changes: 6 additions & 5 deletions src/api/filesystem/sync_io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -313,9 +313,9 @@ pub trait FileSystem {
inode: Self::Inode,
flags: u32,
fuse_flags: u32,
) -> io::Result<(Option<Self::Handle>, OpenOptions)> {
) -> io::Result<(Option<Self::Handle>, OpenOptions, Option<u32>)> {
// Matches the behavior of libfuse.
Ok((None, OpenOptions::empty()))
Ok((None, OpenOptions::empty(), None))
}

/// Create and open a file.
Expand All @@ -332,13 +332,14 @@ pub trait FileSystem {
/// addition to the optional `Handle` and the `OpenOptions`, the file system must also return an
/// `Entry` for the file. This increases the lookup count for the `Inode` associated with the
/// file by 1.
#[allow(clippy::type_complexity)]
fn create(
&self,
ctx: &Context,
parent: Self::Inode,
name: &CStr,
args: CreateIn,
) -> io::Result<(Entry, Option<Self::Handle>, OpenOptions)> {
) -> io::Result<(Entry, Option<Self::Handle>, OpenOptions, Option<u32>)> {
Err(io::Error::from_raw_os_error(libc::ENOSYS))
}

Expand Down Expand Up @@ -1021,7 +1022,7 @@ impl<FS: FileSystem> FileSystem for Arc<FS> {
inode: Self::Inode,
flags: u32,
fuse_flags: u32,
) -> io::Result<(Option<Self::Handle>, OpenOptions)> {
) -> io::Result<(Option<Self::Handle>, OpenOptions, Option<u32>)> {
self.deref().open(ctx, inode, flags, fuse_flags)
}

Expand All @@ -1031,7 +1032,7 @@ impl<FS: FileSystem> FileSystem for Arc<FS> {
parent: Self::Inode,
name: &CStr,
args: CreateIn,
) -> io::Result<(Entry, Option<Self::Handle>, OpenOptions)> {
) -> io::Result<(Entry, Option<Self::Handle>, OpenOptions, Option<u32>)> {
self.deref().create(ctx, parent, name, args)
}

Expand Down
9 changes: 5 additions & 4 deletions src/api/server/sync_io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -390,11 +390,11 @@ impl<F: FileSystem + Sync> Server<F> {
let OpenIn { flags, fuse_flags } = ctx.r.read_obj().map_err(Error::DecodeMessage)?;

match self.fs.open(ctx.context(), ctx.nodeid(), flags, fuse_flags) {
Ok((handle, opts)) => {
Ok((handle, opts, passthrough)) => {
let out = OpenOut {
fh: handle.map(Into::into).unwrap_or(0),
open_flags: opts.bits(),
..Default::default()
passthrough: passthrough.unwrap_or_default(),
};

ctx.reply_ok(Some(out), None)
Expand Down Expand Up @@ -973,7 +973,7 @@ impl<F: FileSystem + Sync> Server<F> {
})?;

match self.fs.create(ctx.context(), ctx.nodeid(), name, args) {
Ok((entry, handle, opts)) => {
Ok((entry, handle, opts, passthrough)) => {
let entry_out = EntryOut {
nodeid: entry.inode,
generation: entry.generation,
Expand All @@ -983,10 +983,11 @@ impl<F: FileSystem + Sync> Server<F> {
attr_valid_nsec: entry.attr_timeout.subsec_nanos(),
attr: entry.attr.into(),
};

let open_out = OpenOut {
fh: handle.map(Into::into).unwrap_or(0),
open_flags: opts.bits(),
..Default::default()
passthrough: passthrough.unwrap_or_default(),
};

// Kind of a hack to write both structs.
Expand Down
8 changes: 6 additions & 2 deletions src/api/vfs/async_io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,9 @@ impl AsyncFileSystem for Vfs {
Err(Error::from_raw_os_error(libc::ENOSYS))
} else {
match self.get_real_rootfs(inode)? {
(Left(fs), idata) => fs.open(ctx, idata.ino(), flags, fuse_flags),
(Left(fs), idata) => fs
.open(ctx, idata.ino(), flags, fuse_flags)
.map(|(a, b, _)| (a, b)),
(Right(fs), idata) => fs
.async_open(ctx, idata.ino(), flags, fuse_flags)
.await
Expand All @@ -90,7 +92,9 @@ impl AsyncFileSystem for Vfs {
validate_path_component(name)?;

match self.get_real_rootfs(parent)? {
(Left(fs), idata) => fs.create(ctx, idata.ino(), name, args),
(Left(fs), idata) => fs
.create(ctx, idata.ino(), name, args)
.map(|(a, b, c, _)| (a, b, c)),
(Right(fs), idata) => {
fs.async_create(ctx, idata.ino(), name, args)
.await
Expand Down
10 changes: 5 additions & 5 deletions src/api/vfs/sync_io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ impl FileSystem for Vfs {
inode: VfsInode,
flags: u32,
fuse_flags: u32,
) -> Result<(Option<u64>, OpenOptions)> {
) -> Result<(Option<u64>, OpenOptions, Option<u32>)> {
#[cfg(target_os = "linux")]
if self.opts.load().no_open {
return Err(Error::from_raw_os_error(libc::ENOSYS));
Expand All @@ -308,7 +308,7 @@ impl FileSystem for Vfs {
(Left(fs), idata) => fs.open(ctx, idata.ino(), flags, fuse_flags),
(Right(fs), idata) => fs
.open(ctx, idata.ino(), flags, fuse_flags)
.map(|(h, opt)| (h.map(Into::into), opt)),
.map(|(h, opt, passthrough)| (h.map(Into::into), opt, passthrough)),
}
}

Expand All @@ -318,16 +318,16 @@ impl FileSystem for Vfs {
parent: VfsInode,
name: &CStr,
args: CreateIn,
) -> Result<(Entry, Option<u64>, OpenOptions)> {
) -> Result<(Entry, Option<u64>, OpenOptions, Option<u32>)> {
validate_path_component(name)?;

match self.get_real_rootfs(parent)? {
(Left(fs), idata) => fs.create(ctx, idata.ino(), name, args),
(Right(fs), idata) => {
fs.create(ctx, idata.ino(), name, args)
.map(|(mut a, b, c)| {
.map(|(mut a, b, c, d)| {
self.convert_entry(idata.fs_idx(), a.inode, &mut a)?;
Ok((a, b, c))
Ok((a, b, c, d))
})?
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/passthrough/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1689,7 +1689,7 @@ mod tests {
umask: 0,
fuse_flags: 0,
};
let (entry, handle, _) = fs.create(&ctx, ROOT_ID, &fname, args).unwrap();
let (entry, handle, _, _) = fs.create(&ctx, ROOT_ID, &fname, args).unwrap();
let handle_data = fs.handle_map.get(handle.unwrap(), entry.inode).unwrap();
let mut f = unsafe { File::from_raw_fd(handle_data.get_handle_raw_fd()) };
let mut buf = [0; 4];
Expand All @@ -1700,7 +1700,7 @@ mod tests {
// Then Open an existing file with O_WRONLY, we should be able to read it as well.
let fname = CString::new("existfile").unwrap();
let entry = fs.lookup(&ctx, ROOT_ID, &fname).unwrap();
let (handle, _) = fs
let (handle, _, _) = fs
.open(&ctx, entry.inode, libc::O_WRONLY as u32, 0)
.unwrap();
let handle_data = fs.handle_map.get(handle.unwrap(), entry.inode).unwrap();
Expand Down
11 changes: 6 additions & 5 deletions src/passthrough/sync_io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ impl<S: BitmapSlice + Send + Sync> PassthroughFs<S> {
inode: Inode,
flags: u32,
fuse_flags: u32,
) -> io::Result<(Option<Handle>, OpenOptions)> {
) -> io::Result<(Option<Handle>, OpenOptions, Option<u32>)> {
let killpriv = if self.killpriv_v2.load(Ordering::Relaxed)
&& (fuse_flags & FOPEN_IN_KILL_SUIDGID != 0)
{
Expand All @@ -204,7 +204,7 @@ impl<S: BitmapSlice + Send + Sync> PassthroughFs<S> {
_ => {}
};

Ok((Some(handle), opts))
Ok((Some(handle), opts, None))
}

fn do_getattr(
Expand Down Expand Up @@ -396,6 +396,7 @@ impl<S: BitmapSlice + Send + Sync> FileSystem for PassthroughFs<S> {
Err(io::Error::from_raw_os_error(libc::ENOSYS))
} else {
self.do_open(inode, flags | (libc::O_DIRECTORY as u32), 0)
.map(|(a, b, _)| (a, b))
}
}

Expand Down Expand Up @@ -516,7 +517,7 @@ impl<S: BitmapSlice + Send + Sync> FileSystem for PassthroughFs<S> {
inode: Inode,
flags: u32,
fuse_flags: u32,
) -> io::Result<(Option<Handle>, OpenOptions)> {
) -> io::Result<(Option<Handle>, OpenOptions, Option<u32>)> {
if self.no_open.load(Ordering::Relaxed) {
info!("fuse: open is not supported.");
Err(io::Error::from_raw_os_error(libc::ENOSYS))
Expand Down Expand Up @@ -548,7 +549,7 @@ impl<S: BitmapSlice + Send + Sync> FileSystem for PassthroughFs<S> {
parent: Inode,
name: &CStr,
args: CreateIn,
) -> io::Result<(Entry, Option<Handle>, OpenOptions)> {
) -> io::Result<(Entry, Option<Handle>, OpenOptions, Option<u32>)> {
self.validate_path_component(name)?;

let dir = self.inode_map.get(parent)?;
Expand Down Expand Up @@ -604,7 +605,7 @@ impl<S: BitmapSlice + Send + Sync> FileSystem for PassthroughFs<S> {
_ => {}
};

Ok((entry, ret_handle, opts))
Ok((entry, ret_handle, opts, None))
}

fn unlink(&self, _ctx: &Context, parent: Inode, name: &CStr) -> io::Result<()> {
Expand Down