Skip to content

File tree

8 files changed

+40
-25
lines changed

8 files changed

+40
-25
lines changed

src/abi/fuse_abi_linux.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,11 @@ const INIT_EXT: u64 = 0x4000_0000;
197197
// This flag indicates whether the guest kernel enable per-file dax
198198
const PERFILE_DAX: u64 = 0x2_0000_0000;
199199

200+
// This flag indicates whether to enable fd-passthrough. It was defined in the
201+
// Anolis kernel but not in the upstream kernel. To avoid collision, we'll set
202+
// it to the most significant bit.
203+
const FD_PASSTHROUGH: u64 = 0x8000_0000_0000_0000;
204+
200205
/**
201206
*
202207
* fuse_attr flags
@@ -442,6 +447,9 @@ bitflags! {
442447
/// -. write has WRITE_KILL_PRIV
443448
const HANDLE_KILLPRIV_V2 = HANDLE_KILLPRIV_V2;
444449

450+
/// Indicates the kernel support fuse fd passthrough.
451+
const FD_PASSTHROUGH = FD_PASSTHROUGH;
452+
445453
/// The fuse_init_in is extended.
446454
const INIT_EXT = INIT_EXT;
447455

@@ -910,7 +918,7 @@ unsafe impl ByteValued for CreateIn {}
910918
pub struct OpenOut {
911919
pub fh: u64,
912920
pub open_flags: u32,
913-
pub padding: u32,
921+
pub passthrough: u32,
914922
}
915923
unsafe impl ByteValued for OpenOut {}
916924

src/abi/fuse_abi_macos.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -683,7 +683,7 @@ unsafe impl ByteValued for CreateIn {}
683683
pub struct OpenOut {
684684
pub fh: u64,
685685
pub open_flags: u32,
686-
pub padding: u32,
686+
pub passthrough: u32,
687687
}
688688
unsafe impl ByteValued for OpenOut {}
689689

src/api/filesystem/sync_io.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -313,9 +313,9 @@ pub trait FileSystem {
313313
inode: Self::Inode,
314314
flags: u32,
315315
fuse_flags: u32,
316-
) -> io::Result<(Option<Self::Handle>, OpenOptions)> {
316+
) -> io::Result<(Option<Self::Handle>, OpenOptions, Option<u32>)> {
317317
// Matches the behavior of libfuse.
318-
Ok((None, OpenOptions::empty()))
318+
Ok((None, OpenOptions::empty(), None))
319319
}
320320

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

@@ -1021,7 +1022,7 @@ impl<FS: FileSystem> FileSystem for Arc<FS> {
10211022
inode: Self::Inode,
10221023
flags: u32,
10231024
fuse_flags: u32,
1024-
) -> io::Result<(Option<Self::Handle>, OpenOptions)> {
1025+
) -> io::Result<(Option<Self::Handle>, OpenOptions, Option<u32>)> {
10251026
self.deref().open(ctx, inode, flags, fuse_flags)
10261027
}
10271028

@@ -1031,7 +1032,7 @@ impl<FS: FileSystem> FileSystem for Arc<FS> {
10311032
parent: Self::Inode,
10321033
name: &CStr,
10331034
args: CreateIn,
1034-
) -> io::Result<(Entry, Option<Self::Handle>, OpenOptions)> {
1035+
) -> io::Result<(Entry, Option<Self::Handle>, OpenOptions, Option<u32>)> {
10351036
self.deref().create(ctx, parent, name, args)
10361037
}
10371038

src/api/server/sync_io.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -390,11 +390,11 @@ impl<F: FileSystem + Sync> Server<F> {
390390
let OpenIn { flags, fuse_flags } = ctx.r.read_obj().map_err(Error::DecodeMessage)?;
391391

392392
match self.fs.open(ctx.context(), ctx.nodeid(), flags, fuse_flags) {
393-
Ok((handle, opts)) => {
393+
Ok((handle, opts, passthrough)) => {
394394
let out = OpenOut {
395395
fh: handle.map(Into::into).unwrap_or(0),
396396
open_flags: opts.bits(),
397-
..Default::default()
397+
passthrough: passthrough.unwrap_or_default(),
398398
};
399399

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

975975
match self.fs.create(ctx.context(), ctx.nodeid(), name, args) {
976-
Ok((entry, handle, opts)) => {
976+
Ok((entry, handle, opts, passthrough)) => {
977977
let entry_out = EntryOut {
978978
nodeid: entry.inode,
979979
generation: entry.generation,
@@ -983,10 +983,11 @@ impl<F: FileSystem + Sync> Server<F> {
983983
attr_valid_nsec: entry.attr_timeout.subsec_nanos(),
984984
attr: entry.attr.into(),
985985
};
986+
986987
let open_out = OpenOut {
987988
fh: handle.map(Into::into).unwrap_or(0),
988989
open_flags: opts.bits(),
989-
..Default::default()
990+
passthrough: passthrough.unwrap_or_default(),
990991
};
991992

992993
// Kind of a hack to write both structs.

src/api/vfs/async_io.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,9 @@ impl AsyncFileSystem for Vfs {
7171
Err(Error::from_raw_os_error(libc::ENOSYS))
7272
} else {
7373
match self.get_real_rootfs(inode)? {
74-
(Left(fs), idata) => fs.open(ctx, idata.ino(), flags, fuse_flags),
74+
(Left(fs), idata) => fs
75+
.open(ctx, idata.ino(), flags, fuse_flags)
76+
.map(|(a, b, _)| (a, b)),
7577
(Right(fs), idata) => fs
7678
.async_open(ctx, idata.ino(), flags, fuse_flags)
7779
.await
@@ -90,7 +92,9 @@ impl AsyncFileSystem for Vfs {
9092
validate_path_component(name)?;
9193

9294
match self.get_real_rootfs(parent)? {
93-
(Left(fs), idata) => fs.create(ctx, idata.ino(), name, args),
95+
(Left(fs), idata) => fs
96+
.create(ctx, idata.ino(), name, args)
97+
.map(|(a, b, c, _)| (a, b, c)),
9498
(Right(fs), idata) => {
9599
fs.async_create(ctx, idata.ino(), name, args)
96100
.await

src/api/vfs/sync_io.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ impl FileSystem for Vfs {
299299
inode: VfsInode,
300300
flags: u32,
301301
fuse_flags: u32,
302-
) -> Result<(Option<u64>, OpenOptions)> {
302+
) -> Result<(Option<u64>, OpenOptions, Option<u32>)> {
303303
#[cfg(target_os = "linux")]
304304
if self.opts.load().no_open {
305305
return Err(Error::from_raw_os_error(libc::ENOSYS));
@@ -308,7 +308,7 @@ impl FileSystem for Vfs {
308308
(Left(fs), idata) => fs.open(ctx, idata.ino(), flags, fuse_flags),
309309
(Right(fs), idata) => fs
310310
.open(ctx, idata.ino(), flags, fuse_flags)
311-
.map(|(h, opt)| (h.map(Into::into), opt)),
311+
.map(|(h, opt, passthrough)| (h.map(Into::into), opt, passthrough)),
312312
}
313313
}
314314

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

324324
match self.get_real_rootfs(parent)? {
325325
(Left(fs), idata) => fs.create(ctx, idata.ino(), name, args),
326326
(Right(fs), idata) => {
327327
fs.create(ctx, idata.ino(), name, args)
328-
.map(|(mut a, b, c)| {
328+
.map(|(mut a, b, c, d)| {
329329
self.convert_entry(idata.fs_idx(), a.inode, &mut a)?;
330-
Ok((a, b, c))
330+
Ok((a, b, c, d))
331331
})?
332332
}
333333
}

src/passthrough/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1224,7 +1224,7 @@ mod tests {
12241224
umask: 0,
12251225
fuse_flags: 0,
12261226
};
1227-
let (entry, handle, _) = fs.create(&ctx, ROOT_ID, &fname, args).unwrap();
1227+
let (entry, handle, _, _) = fs.create(&ctx, ROOT_ID, &fname, args).unwrap();
12281228
let handle_data = fs.handle_map.get(handle.unwrap(), entry.inode).unwrap();
12291229
let mut f = unsafe { File::from_raw_fd(handle_data.get_handle_raw_fd()) };
12301230
let mut buf = [0; 4];
@@ -1235,7 +1235,7 @@ mod tests {
12351235
// Then Open an existing file with O_WRONLY, we should be able to read it as well.
12361236
let fname = CString::new("existfile").unwrap();
12371237
let entry = fs.lookup(&ctx, ROOT_ID, &fname).unwrap();
1238-
let (handle, _) = fs
1238+
let (handle, _, _) = fs
12391239
.open(&ctx, entry.inode, libc::O_WRONLY as u32, 0)
12401240
.unwrap();
12411241
let handle_data = fs.handle_map.get(handle.unwrap(), entry.inode).unwrap();

src/passthrough/sync_io.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ impl<S: BitmapSlice + Send + Sync> PassthroughFs<S> {
181181
inode: Inode,
182182
flags: u32,
183183
fuse_flags: u32,
184-
) -> io::Result<(Option<Handle>, OpenOptions)> {
184+
) -> io::Result<(Option<Handle>, OpenOptions, Option<u32>)> {
185185
let killpriv = if self.killpriv_v2.load(Ordering::Relaxed)
186186
&& (fuse_flags & FOPEN_IN_KILL_SUIDGID != 0)
187187
{
@@ -207,7 +207,7 @@ impl<S: BitmapSlice + Send + Sync> PassthroughFs<S> {
207207
_ => {}
208208
};
209209

210-
Ok((Some(handle), opts))
210+
Ok((Some(handle), opts, None))
211211
}
212212

213213
fn do_getattr(
@@ -384,6 +384,7 @@ impl<S: BitmapSlice + Send + Sync> FileSystem for PassthroughFs<S> {
384384
Err(enosys())
385385
} else {
386386
self.do_open(inode, flags | (libc::O_DIRECTORY as u32), 0)
387+
.map(|(a, b, _)| (a, b))
387388
}
388389
}
389390

@@ -504,7 +505,7 @@ impl<S: BitmapSlice + Send + Sync> FileSystem for PassthroughFs<S> {
504505
inode: Inode,
505506
flags: u32,
506507
fuse_flags: u32,
507-
) -> io::Result<(Option<Handle>, OpenOptions)> {
508+
) -> io::Result<(Option<Handle>, OpenOptions, Option<u32>)> {
508509
if self.no_open.load(Ordering::Relaxed) {
509510
info!("fuse: open is not supported.");
510511
Err(enosys())
@@ -536,7 +537,7 @@ impl<S: BitmapSlice + Send + Sync> FileSystem for PassthroughFs<S> {
536537
parent: Inode,
537538
name: &CStr,
538539
args: CreateIn,
539-
) -> io::Result<(Entry, Option<Handle>, OpenOptions)> {
540+
) -> io::Result<(Entry, Option<Handle>, OpenOptions, Option<u32>)> {
540541
self.validate_path_component(name)?;
541542

542543
let dir = self.inode_map.get(parent)?;
@@ -587,7 +588,7 @@ impl<S: BitmapSlice + Send + Sync> FileSystem for PassthroughFs<S> {
587588
_ => {}
588589
};
589590

590-
Ok((entry, ret_handle, opts))
591+
Ok((entry, ret_handle, opts, None))
591592
}
592593

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

0 commit comments

Comments
 (0)