1use std::{
2 ffi::{CStr, OsStr},
3 os::unix::ffi::OsStrExt,
4};
5
6use crate::{
7 io::{Ino, Ttl},
8 proto,
9 sealed::Sealed,
10 util::OutputChain,
11 Done, Operation, Reply, Request,
12};
13
14use bytemuck::{bytes_of, Pod};
15
16pub mod traits;
17
18pub use dir::{BufferedReaddir, Lookup, Readdir};
19pub use entry::{Link, Mkdir, Mknod, Rmdir, Symlink, Unlink};
20pub use global::{Init, Statfs};
21pub use inode::{Bmap, Forget, Getattr};
22pub use open::{Access, Create, Open, Opendir, Release, Releasedir};
23pub use rw::{Flush, Fsync, Fsyncdir, Read, Readlink, Write};
24pub use xattr::{Getxattr, Listxattr, Removexattr, Setxattr};
25
26mod dir;
27mod entry;
28mod global;
29mod inode;
30mod open;
31mod rw;
32mod xattr;
33
34pub(crate) use global::InitState;
35
36pub trait FromRequest<'o, O: Operation<'o>> {
37 fn from_request(request: &Request<'o, O>) -> Self;
39}
40
41pub enum Any {}
42
43impl Sealed for Any {}
44
45impl<'o> Operation<'o> for Any {
46 type RequestBody = ();
47 type ReplyState = ();
48}
49
50impl<'o, O: Operation<'o>> FromRequest<'o, O> for () {
51 fn from_request(_request: &Request<'o, O>) -> Self {}
52}
53
54impl<'o, O: Operation<'o>> Reply<'o, O> {
55 fn empty(self) -> Done<'o> {
56 self.chain(OutputChain::empty())
57 }
58
59 fn single<P: Pod>(self, single: &P) -> Done<'o> {
60 self.chain(OutputChain::tail(&[bytes_of(single)]))
61 }
62
63 fn inner(self, deref: impl FnOnce(&Self) -> &[u8]) -> Done<'o> {
64 let result = self
65 .session
66 .ok(self.unique, OutputChain::tail(&[deref(&self)]));
67 self.finish(result)
68 }
69
70 fn chain(self, chain: OutputChain<'_>) -> Done<'o> {
71 let result = self.session.ok(self.unique, chain);
72 self.finish(result)
73 }
74}
75
76fn make_entry(
77 (Ino(ino), entry_ttl): (Ino, Ttl),
78 (attrs, attr_ttl): (proto::Attrs, Ttl),
79) -> proto::EntryOut {
80 proto::EntryOut {
81 nodeid: ino,
82 generation: 0, entry_valid: entry_ttl.seconds(),
84 attr_valid: attr_ttl.seconds(),
85 entry_valid_nsec: entry_ttl.nanoseconds(),
86 attr_valid_nsec: attr_ttl.nanoseconds(),
87 attr: attrs,
88 }
89}
90
91fn c_to_os(c_str: &CStr) -> &OsStr {
92 OsStr::from_bytes(c_str.to_bytes())
93}