Skip to content

Commit bbba3db

Browse files
authored
Allow users to create Notifier objects when handling requests (#303)
* Allow users to create Notifier objects when handling requests * Pass a Notifier to poll() implementations This allows filesystems to respond directly to poll requests without having saved a notifier at session creation time.
1 parent 0554c95 commit bbba3db

File tree

5 files changed

+48
-10
lines changed

5 files changed

+48
-10
lines changed

examples/poll.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use libc::{EACCES, EBADF, EBUSY, EINVAL, ENOENT, ENOTDIR};
2323

2424
use fuser::{
2525
consts::{FOPEN_DIRECT_IO, FOPEN_NONSEEKABLE, FUSE_POLL_SCHEDULE_NOTIFY},
26-
FileAttr, FileType, MountOption, Request, FUSE_ROOT_ID,
26+
FileAttr, FileType, MountOption, PollHandle, Request, FUSE_ROOT_ID,
2727
};
2828

2929
const NUMFILES: u8 = 16;
@@ -251,7 +251,7 @@ impl fuser::Filesystem for FSelFS {
251251
_req: &Request,
252252
_ino: u64,
253253
fh: u64,
254-
kh: u64,
254+
ph: PollHandle,
255255
_events: u32,
256256
flags: u32,
257257
reply: fuser::ReplyPoll,
@@ -271,7 +271,7 @@ impl fuser::Filesystem for FSelFS {
271271

272272
if flags & FUSE_POLL_SCHEDULE_NOTIFY != 0 {
273273
d.notify_mask |= 1 << idx;
274-
d.poll_handles[idx as usize] = kh;
274+
d.poll_handles[idx as usize] = ph.into();
275275
}
276276

277277
let nbytes = d.bytecnt[idx as usize];

src/lib.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use crate::session::MAX_WRITE_SIZE;
2828
pub use ll::fuse_abi::fuse_forget_one;
2929
pub use mnt::mount_options::MountOption;
3030
#[cfg(feature = "abi-7-11")]
31-
pub use notify::Notifier;
31+
pub use notify::{Notifier, PollHandle};
3232
#[cfg(feature = "abi-7-11")]
3333
pub use reply::ReplyPoll;
3434
#[cfg(target_os = "macos")]
@@ -884,14 +884,14 @@ pub trait Filesystem {
884884
_req: &Request<'_>,
885885
ino: u64,
886886
fh: u64,
887-
kh: u64,
887+
ph: PollHandle,
888888
events: u32,
889889
flags: u32,
890890
reply: ReplyPoll,
891891
) {
892892
debug!(
893-
"[Not Implemented] poll(ino: {:#x?}, fh: {}, kh: {}, events: {}, flags: {})",
894-
ino, fh, kh, events, flags
893+
"[Not Implemented] poll(ino: {:#x?}, fh: {}, ph: {:?}, events: {}, flags: {})",
894+
ino, fh, ph, events, flags
895895
);
896896
reply.error(ENOSYS);
897897
}

src/notify.rs

+35-1
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,42 @@ use crate::{
1313
reply::ReplySender,
1414
};
1515

16+
/// A handle to a pending poll() request. Can be saved and used to notify the
17+
/// kernel when a poll is ready.
18+
#[derive(Clone)]
19+
pub struct PollHandle {
20+
handle: u64,
21+
notifier: Notifier,
22+
}
23+
24+
impl PollHandle {
25+
pub(crate) fn new(cs: ChannelSender, kh: u64) -> Self {
26+
Self {
27+
handle: kh,
28+
notifier: Notifier::new(cs),
29+
}
30+
}
31+
32+
/// Notify the kernel that the associated file handle is ready to be polled.
33+
pub fn notify(self) -> io::Result<()> {
34+
self.notifier.poll(self.handle)
35+
}
36+
}
37+
38+
impl From<PollHandle> for u64 {
39+
fn from(value: PollHandle) -> Self {
40+
value.handle
41+
}
42+
}
43+
44+
impl std::fmt::Debug for PollHandle {
45+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
46+
f.debug_tuple("PollHandle").field(&self.handle).finish()
47+
}
48+
}
49+
1650
/// A handle by which the application can send notifications to the server
17-
#[derive(Debug)]
51+
#[derive(Debug, Clone)]
1852
pub struct Notifier(ChannelSender);
1953

2054
impl Notifier {

src/request.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ use crate::reply::ReplyDirectoryPlus;
1919
use crate::reply::{Reply, ReplyDirectory, ReplySender};
2020
use crate::session::{Session, SessionACL};
2121
use crate::Filesystem;
22+
#[cfg(feature = "abi-7-11")]
23+
use crate::PollHandle;
2224
use crate::{ll, KernelConfig};
2325

2426
/// Request data structure
@@ -522,11 +524,13 @@ impl<'a> Request<'a> {
522524
}
523525
#[cfg(feature = "abi-7-11")]
524526
ll::Operation::Poll(x) => {
527+
let ph = PollHandle::new(se.ch.sender(), x.kernel_handle());
528+
525529
se.filesystem.poll(
526530
self,
527531
self.request.nodeid().into(),
528532
x.file_handle().into(),
529-
x.kernel_handle(),
533+
ph,
530534
x.events(),
531535
x.flags(),
532536
self.reply(),

src/session.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ pub struct Session<FS: Filesystem> {
4444
/// Filesystem operation implementations
4545
pub(crate) filesystem: FS,
4646
/// Communication channel to the kernel driver
47-
ch: Channel,
47+
pub(crate) ch: Channel,
4848
/// Handle to the mount. Dropping this unmounts.
4949
mount: Arc<Mutex<Option<Mount>>>,
5050
/// Mount point

0 commit comments

Comments
 (0)