libfuse_fs/passthrough/
newlogfs.rs

1use super::Inode;
2use bytes::Bytes;
3use rfuse3::notify::Notify;
4use rfuse3::raw::reply::*;
5use rfuse3::raw::{Filesystem, Request, reply::ReplyInit};
6use rfuse3::{Result, SetAttr};
7use std::any::type_name_of_val;
8use std::ffi::OsStr;
9use std::sync::atomic::{AtomicU64, Ordering};
10// LoggingFileSystem . provide log info for a filesystem trait.
11pub struct LoggingFileSystem<FS: Filesystem> {
12    inner: FS,
13    fsname: String,
14    next_log_id: AtomicU64,
15}
16
17impl<FS: Filesystem> LoggingFileSystem<FS> {
18    pub fn new(fs: FS) -> Self {
19        let fsname = type_name_of_val(&fs);
20        Self {
21            inner: fs,
22            fsname: String::from(fsname),
23            next_log_id: AtomicU64::new(1),
24        }
25    }
26}
27impl<FS: Filesystem> LoggingFileSystem<FS> {
28    fn log_start(&self, req: &Request, id: u64, method: &str, args: &[(&str, String)]) {
29        let args_str = args
30            .iter()
31            .map(|(k, v)| format!("{k}={v}"))
32            .collect::<Vec<_>>()
33            .join(", ");
34        println!("ID: {id} | [{method}] REQ {req:?} - Call_arg: {args_str}");
35    }
36
37    fn log_result(&self, id: u64, method: &str, result: &Result<impl std::fmt::Debug>) {
38        match result {
39            Ok(res) => println!("ID: {id} | [{method}] - Success: {res:?}"),
40            Err(e) => println!("ID: {id} | [{method}] - Error: {e:?}"),
41        }
42    }
43}
44
45impl<FS: rfuse3::raw::Filesystem + std::marker::Sync> Filesystem for LoggingFileSystem<FS> {
46    type DirEntryStream<'a>
47        = FS::DirEntryStream<'a>
48    where
49        Self: 'a;
50    type DirEntryPlusStream<'a>
51        = FS::DirEntryPlusStream<'a>
52    where
53        Self: 'a;
54
55    async fn init(&self, req: Request) -> Result<ReplyInit> {
56        let id = self.next_log_id.fetch_add(1, Ordering::Relaxed);
57        let method = "init";
58        self.log_start(&req, id, method, &[]);
59        let result = self.inner.init(req).await;
60        self.log_result(id, method, &result);
61        result
62    }
63
64    async fn destroy(&self, req: Request) {
65        let id = self.next_log_id.fetch_add(1, Ordering::Relaxed);
66        let method = "destroy";
67        self.log_start(&req, id, method, &[]);
68        self.inner.destroy(req).await;
69        println!("ID: {} [{}] {} - Completed", id, self.fsname, method);
70    }
71
72    async fn lookup(&self, req: Request, parent: Inode, name: &OsStr) -> Result<ReplyEntry> {
73        let id = self.next_log_id.fetch_add(1, Ordering::Relaxed);
74        let method = "lookup";
75        let args = vec![
76            ("parent", parent.to_string()),
77            ("name", name.to_string_lossy().into_owned()),
78        ];
79        self.log_start(&req, id, method, &args);
80        let result = self.inner.lookup(req, parent, name).await;
81        self.log_result(id, method, &result);
82        result
83    }
84
85    async fn forget(&self, req: Request, inode: Inode, nlookup: u64) {
86        let id = self.next_log_id.fetch_add(1, Ordering::Relaxed);
87        let method = "forget";
88        let args = vec![
89            ("inode", inode.to_string()),
90            ("nlookup", nlookup.to_string()),
91        ];
92        self.log_start(&req, id, method, &args);
93        self.inner.forget(req, inode, nlookup).await;
94        println!("ID: {} [{}] {} - Completed", id, self.fsname, method);
95    }
96
97    async fn getattr(
98        &self,
99        req: Request,
100        inode: Inode,
101        fh: Option<u64>,
102        flags: u32,
103    ) -> Result<ReplyAttr> {
104        let id = self.next_log_id.fetch_add(1, Ordering::Relaxed);
105        let method = "getattr";
106        let args = vec![
107            ("inode", inode.to_string()),
108            ("fh", fh.map(|v| v.to_string()).unwrap_or_default()),
109            ("flags", flags.to_string()),
110        ];
111        self.log_start(&req, id, method, &args);
112        let result = self.inner.getattr(req, inode, fh, flags).await;
113        self.log_result(id, method, &result);
114        result
115    }
116
117    async fn setattr(
118        &self,
119        req: Request,
120        inode: Inode,
121        fh: Option<u64>,
122        set_attr: SetAttr,
123    ) -> Result<ReplyAttr> {
124        let id = self.next_log_id.fetch_add(1, Ordering::Relaxed);
125        let method = "setattr";
126        let args = vec![
127            ("inode", inode.to_string()),
128            ("fh", fh.map(|v| v.to_string()).unwrap_or_default()),
129            ("set_attr", format!("{set_attr:?}")),
130        ];
131        self.log_start(&req, id, method, &args);
132        let result = self.inner.setattr(req, inode, fh, set_attr).await;
133        self.log_result(id, method, &result);
134        result
135    }
136
137    async fn readdirplus(
138        &self,
139        req: Request,
140        parent: Inode,
141        fh: u64,
142        offset: u64,
143        lock_owner: u64,
144    ) -> Result<ReplyDirectoryPlus<Self::DirEntryPlusStream<'_>>> {
145        let id = self.next_log_id.fetch_add(1, Ordering::Relaxed);
146        let method = "readdirplus";
147        let args = vec![
148            ("parent", parent.to_string()),
149            ("fh", fh.to_string()),
150            ("offset", offset.to_string()),
151            ("lock_owner", lock_owner.to_string()),
152        ];
153        self.log_start(&req, id, method, &args);
154        let result = self
155            .inner
156            .readdirplus(req, parent, fh, offset, lock_owner)
157            .await;
158        self.log_result(id, method, &Ok(""));
159        result
160    }
161
162    async fn opendir(&self, req: Request, inode: Inode, flags: u32) -> Result<ReplyOpen> {
163        let id = self.next_log_id.fetch_add(1, Ordering::Relaxed);
164        let method = "opendir";
165        let args = vec![("inode", inode.to_string()), ("flags", flags.to_string())];
166        self.log_start(&req, id, method, &args);
167        let result = self.inner.opendir(req, inode, flags).await;
168        if let Ok(ref reply) = result {
169            println!(
170                "ID: {} [{}] {} - Obtained fh: {}",
171                id, self.fsname, method, reply.fh
172            );
173        }
174        self.log_result(id, method, &result);
175        result
176    }
177
178    async fn readdir(
179        &self,
180        req: Request,
181        parent: Inode,
182        fh: u64,
183        offset: i64,
184    ) -> Result<ReplyDirectory<Self::DirEntryStream<'_>>> {
185        let id = self.next_log_id.fetch_add(1, Ordering::Relaxed);
186        let method = "readdir";
187        let args = vec![
188            ("parent", parent.to_string()),
189            ("fh", fh.to_string()),
190            ("offset", offset.to_string()),
191        ];
192        self.log_start(&req, id, method, &args);
193        let result = self.inner.readdir(req, parent, fh, offset).await;
194        self.log_result(id, method, &Ok(""));
195        result
196    }
197
198    async fn read(
199        &self,
200        req: Request,
201        inode: Inode,
202        fh: u64,
203        offset: u64,
204        size: u32,
205    ) -> Result<ReplyData> {
206        let id = self.next_log_id.fetch_add(1, Ordering::Relaxed);
207        let method = "read";
208        let args = vec![
209            ("inode", inode.to_string()),
210            ("fh", fh.to_string()),
211            ("offset", offset.to_string()),
212            ("size", size.to_string()),
213        ];
214        self.log_start(&req, id, method, &args);
215        let result = self.inner.read(req, inode, fh, offset, size).await;
216        if let Ok(ref data) = result {
217            println!(
218                "ID: {} [{}] {} - Read {} bytes",
219                id,
220                self.fsname,
221                method,
222                data.data.len()
223            );
224        }
225
226        // self.log_result(id, method, &result);
227        result
228    }
229
230    async fn write(
231        &self,
232        req: Request,
233        inode: Inode,
234        fh: u64,
235        offset: u64,
236        data: &[u8],
237        write_flags: u32,
238        flags: u32,
239    ) -> Result<ReplyWrite> {
240        let id = self.next_log_id.fetch_add(1, Ordering::Relaxed);
241        let method = "write";
242        let args = vec![
243            ("inode", inode.to_string()),
244            ("fh", fh.to_string()),
245            ("offset", offset.to_string()),
246            ("data_len", data.len().to_string()),
247            ("write_flags", write_flags.to_string()),
248            ("flags", flags.to_string()),
249        ];
250        self.log_start(&req, id, method, &args);
251        let result = self
252            .inner
253            .write(req, inode, fh, offset, data, write_flags, flags)
254            .await;
255        if let Ok(ref reply) = result {
256            println!(
257                "ID: {} [{}] {} - Wrote {} bytes",
258                id, self.fsname, method, reply.written
259            );
260        }
261        self.log_result(id, method, &result);
262        result
263    }
264
265    async fn fsync(&self, req: Request, inode: Inode, fh: u64, datasync: bool) -> Result<()> {
266        let id = self.next_log_id.fetch_add(1, Ordering::Relaxed);
267        let method = "fsync";
268        let args = vec![
269            ("inode", inode.to_string()),
270            ("fh", fh.to_string()),
271            ("datasync", datasync.to_string()),
272        ];
273        self.log_start(&req, id, method, &args);
274        let result = self.inner.fsync(req, inode, fh, datasync).await;
275        self.log_result(id, method, &result);
276        result
277    }
278
279    async fn setxattr(
280        &self,
281        req: Request,
282        inode: Inode,
283        name: &OsStr,
284        value: &[u8],
285        flags: u32,
286        position: u32,
287    ) -> Result<()> {
288        let id = self.next_log_id.fetch_add(1, Ordering::Relaxed);
289        let method = "setxattr";
290        let args = vec![
291            ("inode", inode.to_string()),
292            ("name", name.to_string_lossy().into_owned()),
293            ("value_len", value.len().to_string()),
294            ("flags", flags.to_string()),
295            ("position", position.to_string()),
296        ];
297        self.log_start(&req, id, method, &args);
298        let result = self
299            .inner
300            .setxattr(req, inode, name, value, flags, position)
301            .await;
302        self.log_result(id, method, &result);
303        result
304    }
305
306    async fn rename2(
307        &self,
308        req: Request,
309        parent: Inode,
310        name: &OsStr,
311        new_parent: Inode,
312        new_name: &OsStr,
313        flags: u32,
314    ) -> Result<()> {
315        let id = self.next_log_id.fetch_add(1, Ordering::Relaxed);
316        let method = "rename2";
317        let args = vec![
318            ("parent", parent.to_string()),
319            ("name", name.to_string_lossy().into_owned()),
320            ("new_parent", new_parent.to_string()),
321            ("new_name", new_name.to_string_lossy().into_owned()),
322            ("flags", flags.to_string()),
323        ];
324        self.log_start(&req, id, method, &args);
325        let result = self
326            .inner
327            .rename2(req, parent, name, new_parent, new_name, flags)
328            .await;
329        self.log_result(id, method, &result);
330        result
331    }
332
333    async fn unlink(&self, req: Request, parent: Inode, name: &OsStr) -> Result<()> {
334        let id = self.next_log_id.fetch_add(1, Ordering::Relaxed);
335        let method = "unlink";
336        let args = vec![
337            ("parent", parent.to_string()),
338            ("name", name.to_string_lossy().into_owned()),
339        ];
340        self.log_start(&req, id, method, &args);
341        let re = self.inner.unlink(req, parent, name).await;
342        self.log_result(id, method, &re);
343        re
344    }
345
346    async fn mkdir(
347        &self,
348        req: Request,
349        parent: rfuse3::Inode,
350        name: &OsStr,
351        mode: u32,
352        umask: u32,
353    ) -> Result<ReplyEntry> {
354        let id = self.next_log_id.fetch_add(1, Ordering::Relaxed);
355        let method = "mkdir";
356        let args = vec![
357            ("parent", parent.to_string()),
358            ("name", name.to_string_lossy().into_owned()),
359            ("mode", mode.to_string()),
360            ("umask", umask.to_string()),
361        ];
362        self.log_start(&req, id, method, &args);
363        let result = self.inner.mkdir(req, parent, name, mode, umask).await;
364        self.log_result(id, method, &result);
365        result
366    }
367
368    async fn access(&self, req: Request, inode: rfuse3::Inode, mask: u32) -> Result<()> {
369        let id = self.next_log_id.fetch_add(1, Ordering::Relaxed);
370        let method = "access";
371        let args = vec![("inode", inode.to_string()), ("mask", mask.to_string())];
372        self.log_start(&req, id, method, &args);
373        let result = self.inner.access(req, inode, mask).await;
374        self.log_result(id, method, &result);
375        result
376    }
377
378    async fn getxattr(
379        &self,
380        req: Request,
381        inode: rfuse3::Inode,
382        name: &OsStr,
383        size: u32,
384    ) -> Result<ReplyXAttr> {
385        let id = self.next_log_id.fetch_add(1, Ordering::Relaxed);
386        let method = "getxattr";
387        let args = vec![
388            ("inode", inode.to_string()),
389            ("name", name.to_string_lossy().into_owned()),
390            ("size", size.to_string()),
391        ];
392        self.log_start(&req, id, method, &args);
393        let result = self.inner.getxattr(req, inode, name, size).await;
394        self.log_result(id, method, &result);
395        result
396    }
397
398    async fn create(
399        &self,
400        req: Request,
401        parent: rfuse3::Inode,
402        name: &OsStr,
403        mode: u32,
404        flags: u32,
405    ) -> Result<ReplyCreated> {
406        let id = self.next_log_id.fetch_add(1, Ordering::Relaxed);
407        let method = "create";
408        let args = vec![
409            ("parent", parent.to_string()),
410            ("name", name.to_string_lossy().into_owned()),
411            ("mode", mode.to_string()),
412            ("flags", flags.to_string()),
413        ];
414        self.log_start(&req, id, method, &args);
415        let result = self.inner.create(req, parent, name, mode, flags).await;
416        self.log_result(id, method, &result);
417        result
418    }
419
420    async fn lseek(
421        &self,
422        req: Request,
423        inode: rfuse3::Inode,
424        fh: u64,
425        offset: u64,
426        whence: u32,
427    ) -> Result<ReplyLSeek> {
428        let id = self.next_log_id.fetch_add(1, Ordering::Relaxed);
429        let method = "lseek";
430        let args = vec![
431            ("inode", inode.to_string()),
432            ("fh", fh.to_string()),
433            ("offset", offset.to_string()),
434            ("whence", whence.to_string()),
435        ];
436        self.log_start(&req, id, method, &args);
437        let result = self.inner.lseek(req, inode, fh, offset, whence).await;
438        self.log_result(id, method, &result);
439        result
440    }
441
442    async fn mknod(
443        &self,
444        req: Request,
445        parent: rfuse3::Inode,
446        name: &OsStr,
447        mode: u32,
448        rdev: u32,
449    ) -> Result<ReplyEntry> {
450        let id = self.next_log_id.fetch_add(1, Ordering::Relaxed);
451        let method = "mknod";
452        let args = vec![
453            ("parent", parent.to_string()),
454            ("name", name.to_string_lossy().into_owned()),
455            ("mode", mode.to_string()),
456            ("rdev", rdev.to_string()),
457        ];
458        self.log_start(&req, id, method, &args);
459        let result = self.inner.mknod(req, parent, name, mode, rdev).await;
460        self.log_result(id, method, &result);
461        result
462    }
463
464    async fn rename(
465        &self,
466        req: Request,
467        parent: rfuse3::Inode,
468        name: &OsStr,
469        new_parent: rfuse3::Inode,
470        new_name: &OsStr,
471    ) -> Result<()> {
472        let id = self.next_log_id.fetch_add(1, Ordering::Relaxed);
473        let method = "rename";
474        let args = vec![
475            ("parent", parent.to_string()),
476            ("name", name.to_string_lossy().into_owned()),
477            ("new_parent", new_parent.to_string()),
478            ("new_name", new_name.to_string_lossy().into_owned()),
479        ];
480        self.log_start(&req, id, method, &args);
481        let result = self
482            .inner
483            .rename(req, parent, name, new_parent, new_name)
484            .await;
485        self.log_result(id, method, &result);
486        result
487    }
488    async fn listxattr(&self, req: Request, inode: rfuse3::Inode, size: u32) -> Result<ReplyXAttr> {
489        let id = self.next_log_id.fetch_add(1, Ordering::Relaxed);
490        let method = "listxattr";
491        let args = vec![("inode", inode.to_string()), ("size", size.to_string())];
492        self.log_start(&req, id, method, &args);
493        let result = self.inner.listxattr(req, inode, size).await;
494        self.log_result(id, method, &result);
495        result
496    }
497
498    async fn open(&self, req: Request, inode: rfuse3::Inode, flags: u32) -> Result<ReplyOpen> {
499        let id = self.next_log_id.fetch_add(1, Ordering::Relaxed);
500        let method = "open";
501        let args = vec![("inode", inode.to_string()), ("flags", flags.to_string())];
502        self.log_start(&req, id, method, &args);
503        let result = self.inner.open(req, inode, flags).await;
504        if let Ok(ref reply) = result {
505            println!(
506                "ID: {} [{}] {} - Obtained fh: {}",
507                id, self.fsname, method, reply.fh
508            );
509        }
510        self.log_result(id, method, &result);
511        result
512    }
513
514    async fn rmdir(&self, req: Request, parent: rfuse3::Inode, name: &OsStr) -> Result<()> {
515        let id = self.next_log_id.fetch_add(1, Ordering::Relaxed);
516        let method = "rmdir";
517        let args = vec![
518            ("parent", parent.to_string()),
519            ("name", name.to_string_lossy().into_owned()),
520        ];
521        self.log_start(&req, id, method, &args);
522        let result = self.inner.rmdir(req, parent, name).await;
523        self.log_result(id, method, &result);
524        result
525    }
526
527    async fn statfs(&self, req: Request, inode: rfuse3::Inode) -> Result<ReplyStatFs> {
528        let id = self.next_log_id.fetch_add(1, Ordering::Relaxed);
529        let method = "statfs";
530        let args = vec![("inode", inode.to_string())];
531        self.log_start(&req, id, method, &args);
532        let result = self.inner.statfs(req, inode).await;
533        self.log_result(id, method, &result);
534        result
535    }
536
537    async fn link(
538        &self,
539        req: Request,
540        inode: rfuse3::Inode,
541        new_parent: rfuse3::Inode,
542        new_name: &OsStr,
543    ) -> Result<ReplyEntry> {
544        let id = self.next_log_id.fetch_add(1, Ordering::Relaxed);
545        let method = "link";
546        let args = vec![
547            ("inode", inode.to_string()),
548            ("new_parent", new_parent.to_string()),
549            ("new_name", new_name.to_string_lossy().into_owned()),
550        ];
551        self.log_start(&req, id, method, &args);
552        let result = self.inner.link(req, inode, new_parent, new_name).await;
553        self.log_result(id, method, &result);
554        result
555    }
556
557    async fn symlink(
558        &self,
559        req: Request,
560        parent: rfuse3::Inode,
561        name: &OsStr,
562        link: &OsStr,
563    ) -> Result<ReplyEntry> {
564        let id = self.next_log_id.fetch_add(1, Ordering::Relaxed);
565        let method = "symlink";
566        let args = vec![
567            ("parent", parent.to_string()),
568            ("name", name.to_string_lossy().into_owned()),
569            ("link", link.to_string_lossy().into_owned()),
570        ];
571        self.log_start(&req, id, method, &args);
572        let result = self.inner.symlink(req, parent, name, link).await;
573        self.log_result(id, method, &result);
574        result
575    }
576
577    async fn batch_forget(&self, req: Request, inodes: &[(Inode, u64)]) {
578        let id = self.next_log_id.fetch_add(1, Ordering::Relaxed);
579        let method = "batch_forget";
580        let args = vec![(
581            "inodes",
582            inodes
583                .iter()
584                .map(|inode| inode.0.to_string())
585                .collect::<Vec<_>>()
586                .join(", "),
587        )];
588        self.log_start(&req, id, method, &args);
589        self.inner.batch_forget(req, inodes).await;
590        self.log_result(id, method, &Ok(""));
591    }
592
593    async fn bmap(
594        &self,
595        req: Request,
596        inode: rfuse3::Inode,
597        blocksize: u32,
598        idx: u64,
599    ) -> Result<ReplyBmap> {
600        let id = self.next_log_id.fetch_add(1, Ordering::Relaxed);
601        let method = "bmap";
602        let args = vec![
603            ("inode", inode.to_string()),
604            ("blocksize", blocksize.to_string()),
605            ("idx", idx.to_string()),
606        ];
607        self.log_start(&req, id, method, &args);
608        let result = self.inner.bmap(req, inode, blocksize, idx).await;
609        self.log_result(id, method, &result);
610        result
611    }
612
613    async fn copy_file_range(
614        &self,
615        req: Request,
616        inode: rfuse3::Inode,
617        fh_in: u64,
618        off_in: u64,
619        inode_out: rfuse3::Inode,
620        fh_out: u64,
621        off_out: u64,
622        length: u64,
623        flags: u64,
624    ) -> Result<ReplyCopyFileRange> {
625        let id = self.next_log_id.fetch_add(1, Ordering::Relaxed);
626        let method = "copy_file_range";
627        let args = vec![
628            ("inode", inode.to_string()),
629            ("fh_in", fh_in.to_string()),
630            ("off_in", off_in.to_string()),
631            ("inode_out", inode_out.to_string()),
632            ("fh_out", fh_out.to_string()),
633            ("off_out", off_out.to_string()),
634            ("length", length.to_string()),
635            ("flags", flags.to_string()),
636        ];
637        self.log_start(&req, id, method, &args);
638        let result = self
639            .inner
640            .copy_file_range(
641                req, inode, fh_in, off_in, inode_out, fh_out, off_out, length, flags,
642            )
643            .await;
644        self.log_result(id, method, &result);
645        result
646    }
647
648    async fn fallocate(
649        &self,
650        req: Request,
651        inode: rfuse3::Inode,
652        fh: u64,
653        offset: u64,
654        length: u64,
655        mode: u32,
656    ) -> Result<()> {
657        let id = self.next_log_id.fetch_add(1, Ordering::Relaxed);
658        let method = "fallocate";
659        let args = vec![
660            ("inode", inode.to_string()),
661            ("fh", fh.to_string()),
662            ("offset", offset.to_string()),
663            ("length", length.to_string()),
664            ("mode", mode.to_string()),
665        ];
666        self.log_start(&req, id, method, &args);
667        let result = self
668            .inner
669            .fallocate(req, inode, fh, offset, length, mode)
670            .await;
671        self.log_result(id, method, &result);
672        result
673    }
674
675    async fn flush(
676        &self,
677        req: Request,
678        inode: rfuse3::Inode,
679        fh: u64,
680        lock_owner: u64,
681    ) -> Result<()> {
682        let id = self.next_log_id.fetch_add(1, Ordering::Relaxed);
683        let method = "flush";
684        let args = vec![
685            ("inode", inode.to_string()),
686            ("fh", fh.to_string()),
687            ("lock_owner", lock_owner.to_string()),
688        ];
689        self.log_start(&req, id, method, &args);
690        let result = self.inner.flush(req, inode, fh, lock_owner).await;
691        self.log_result(id, method, &result);
692        result
693    }
694
695    async fn fsyncdir(
696        &self,
697        req: Request,
698        inode: rfuse3::Inode,
699        fh: u64,
700        datasync: bool,
701    ) -> Result<()> {
702        let id = self.next_log_id.fetch_add(1, Ordering::Relaxed);
703        let method = "fsyncdir";
704        let args = vec![
705            ("inode", inode.to_string()),
706            ("fh", fh.to_string()),
707            ("datasync", datasync.to_string()),
708        ];
709        self.log_start(&req, id, method, &args);
710        let result = self.inner.fsyncdir(req, inode, fh, datasync).await;
711        self.log_result(id, method, &result);
712        result
713    }
714
715    // async  fn interrupt(&self, req: Request, unique: u64) -> Result<()> {
716    //     let uuid = Uuid::new_v4();
717    //     let method = "interrupt";
718    //     let args = vec![
719    //         ("unique", unique.to_string())
720    //     ];
721    //     self.log_start(&req,&uuid, method, &args);
722    //     let result = self.inner.interrupt(req, unique).await;
723    //     self.log_result(&uuid, method, &result);
724    //     result
725    // }
726
727    async fn notify_reply(
728        &self,
729        req: Request,
730        inode: rfuse3::Inode,
731        offset: u64,
732        data: Bytes,
733    ) -> Result<()> {
734        let id = self.next_log_id.fetch_add(1, Ordering::Relaxed);
735        let method = "notify_reply";
736        let args = vec![("inode", inode.to_string()), ("offset", offset.to_string())];
737        self.log_start(&req, id, method, &args);
738        let result = self.inner.notify_reply(req, inode, offset, data).await;
739        self.log_result(id, method, &result);
740        result
741    }
742
743    async fn poll(
744        &self,
745        req: Request,
746        inode: rfuse3::Inode,
747        fh: u64,
748        kh: Option<u64>,
749        flags: u32,
750        events: u32,
751        notify: &Notify,
752    ) -> Result<ReplyPoll> {
753        let id = self.next_log_id.fetch_add(1, Ordering::Relaxed);
754        let method = "poll";
755        let args = vec![
756            ("inode", inode.to_string()),
757            ("fh", fh.to_string()),
758            ("flags", flags.to_string()),
759            ("events", events.to_string()),
760        ];
761        self.log_start(&req, id, method, &args);
762        let result = self
763            .inner
764            .poll(req, inode, fh, kh, flags, events, notify)
765            .await;
766        self.log_result(id, method, &result);
767        result
768    }
769
770    async fn readlink(&self, req: Request, inode: rfuse3::Inode) -> Result<ReplyData> {
771        let id = self.next_log_id.fetch_add(1, Ordering::Relaxed);
772        let method = "readlink";
773        let args = vec![("inode", inode.to_string())];
774        self.log_start(&req, id, method, &args);
775        let result = self.inner.readlink(req, inode).await;
776        self.log_result(id, method, &result);
777        result
778    }
779
780    async fn release(
781        &self,
782        req: Request,
783        inode: rfuse3::Inode,
784        fh: u64,
785        flags: u32,
786        lock_owner: u64,
787        flush: bool,
788    ) -> Result<()> {
789        let id = self.next_log_id.fetch_add(1, Ordering::Relaxed);
790        let method = "release";
791        let args = vec![
792            ("inode", inode.to_string()),
793            ("fh", fh.to_string()),
794            ("flags", flags.to_string()),
795            ("lock_owner", lock_owner.to_string()),
796            ("flush", flush.to_string()),
797        ];
798        self.log_start(&req, id, method, &args);
799        let result = self
800            .inner
801            .release(req, inode, fh, flags, lock_owner, flush)
802            .await;
803        self.log_result(id, method, &result);
804        result
805    }
806
807    async fn releasedir(
808        &self,
809        req: Request,
810        inode: rfuse3::Inode,
811        fh: u64,
812        flags: u32,
813    ) -> Result<()> {
814        let id = self.next_log_id.fetch_add(1, Ordering::Relaxed);
815        let method = "releasedir";
816        let args = vec![
817            ("inode", inode.to_string()),
818            ("fh", fh.to_string()),
819            ("flags", flags.to_string()),
820        ];
821        self.log_start(&req, id, method, &args);
822        let result = self.inner.releasedir(req, inode, fh, flags).await;
823        self.log_result(id, method, &result);
824        result
825    }
826
827    async fn removexattr(&self, req: Request, inode: rfuse3::Inode, name: &OsStr) -> Result<()> {
828        let id = self.next_log_id.fetch_add(1, Ordering::Relaxed);
829        let method = "removexattr";
830        let args = vec![
831            ("inode", inode.to_string()),
832            ("name", name.to_string_lossy().to_string()),
833        ];
834        self.log_start(&req, id, method, &args);
835        let result = self.inner.removexattr(req, inode, name).await;
836        self.log_result(id, method, &result);
837        result
838    }
839}