blown_fuse/ops/
mod.rs

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    //TODO: Shouldn't be public
38    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, //TODO
83        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}