1use std::io;
2
3#[allow(unused)]
4use std::{convert::TryInto, ffi::OsStr};
5
6use crate::{
7 channel::ChannelSender,
8 ll::{fuse_abi::fuse_notify_code as notify_code, notify::Notification},
9
10 reply::ReplySender,
14};
15
16#[derive(Clone)]
19pub struct PollHandle {
20 handle: u64,
21 notifier: Notifier,
22}
23
24impl 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 pub fn notify(self) -> io::Result<()> {
34 self.notifier.poll(self.handle)
35 }
36}
37
38impl From<PollHandle> for u64 {
39 fn from(value: PollHandle) -> Self {
40 value.handle
41 }
42}
43
44impl 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
50#[derive(Debug, Clone)]
52pub struct Notifier(ChannelSender);
53
54impl Notifier {
55 pub(crate) fn new(cs: ChannelSender) -> Self {
56 Self(cs)
57 }
58
59 pub fn poll(&self, kh: u64) -> io::Result<()> {
61 let notif = Notification::new_poll(kh);
62 self.send(notify_code::FUSE_POLL, ¬if)
63 }
64
65 pub fn inval_entry(&self, parent: u64, name: &OsStr) -> io::Result<()> {
67 let notif = Notification::new_inval_entry(parent, name).map_err(Self::too_big_err)?;
68 self.send_inval(notify_code::FUSE_NOTIFY_INVAL_ENTRY, ¬if)
69 }
70
71 pub fn inval_inode(&self, ino: u64, offset: i64, len: i64) -> io::Result<()> {
74 let notif = Notification::new_inval_inode(ino, offset, len);
75 self.send_inval(notify_code::FUSE_NOTIFY_INVAL_INODE, ¬if)
76 }
77
78 pub fn store(&self, ino: u64, offset: u64, data: &[u8]) -> io::Result<()> {
80 let notif = Notification::new_store(ino, offset, data).map_err(Self::too_big_err)?;
81 self.send_inval(notify_code::FUSE_NOTIFY_STORE, ¬if)
84 }
85
86 pub fn delete(&self, parent: u64, child: u64, name: &OsStr) -> io::Result<()> {
89 let notif = Notification::new_delete(parent, child, name).map_err(Self::too_big_err)?;
90 self.send_inval(notify_code::FUSE_NOTIFY_DELETE, ¬if)
91 }
92
93 #[allow(unused)]
94 fn send_inval(&self, code: notify_code, notification: &Notification<'_>) -> io::Result<()> {
95 match self.send(code, notification) {
96 Err(e) if e.kind() == io::ErrorKind::NotFound => Ok(()),
100 x => x,
101 }
102 }
103
104 fn send(&self, code: notify_code, notification: &Notification<'_>) -> io::Result<()> {
105 notification
106 .with_iovec(code, |iov| self.0.send(iov))
107 .map_err(Self::too_big_err)?
108 }
109
110 fn too_big_err(tfie: std::num::TryFromIntError) -> io::Error {
114 io::Error::new(io::ErrorKind::Other, format!("Data too large: {tfie:?}"))
115 }
116}