1use super::traits::ReplyOk;
2use crate::{io::FsInfo, proto, sealed::Sealed, util::page_size, Done, Operation, Reply};
3
4pub enum Init {}
5pub enum Statfs {}
6
7pub struct InitState {
8 pub(crate) kernel_flags: proto::InitFlags,
9 pub(crate) buffer_pages: usize,
10}
11
12pub trait ReplyFsInfo<'o>: Operation<'o> {
13 fn info(reply: Reply<'o, Self>, info: &FsInfo) -> Done<'o>;
14}
15
16impl Sealed for Init {}
17impl Sealed for Statfs {}
18
19impl<'o> Operation<'o> for Init {
20 type RequestBody = &'o proto::InitIn;
21 type ReplyState = InitState;
22}
23
24impl<'o> Operation<'o> for Statfs {
25 type RequestBody = ();
26 type ReplyState = ();
27}
28
29impl<'o> ReplyOk<'o> for Init {
30 fn ok(reply: Reply<'o, Self>) -> Done<'o> {
31 let InitState {
32 kernel_flags,
33 buffer_pages,
34 } = reply.state;
35
36 let flags = {
37 use proto::InitFlags;
38
39 let supported = InitFlags::ASYNC_READ
50 | InitFlags::FILE_OPS
51 | InitFlags::ATOMIC_O_TRUNC
52 | InitFlags::EXPORT_SUPPORT
53 | InitFlags::BIG_WRITES
54 | InitFlags::HAS_IOCTL_DIR
55 | InitFlags::AUTO_INVAL_DATA
56 | InitFlags::DO_READDIRPLUS
57 | InitFlags::READDIRPLUS_AUTO
58 | InitFlags::PARALLEL_DIROPS
59 | InitFlags::ABORT_ERROR
60 | InitFlags::MAX_PAGES
61 | InitFlags::CACHE_SYMLINKS;
62
63 kernel_flags & supported
64 };
65
66 let buffer_size = page_size() * buffer_pages;
67
68 let max_write = buffer_size - std::mem::size_of::<(proto::InHeader, proto::WriteIn)>();
70
71 reply.single(&proto::InitOut {
72 major: proto::MAJOR_VERSION,
73 minor: proto::TARGET_MINOR_VERSION,
74 max_readahead: 0, flags: flags.bits(),
76 max_background: 0, congestion_threshold: 0, max_write: max_write.try_into().unwrap(),
79 time_gran: 1, max_pages: buffer_pages.try_into().unwrap(),
81 padding: Default::default(),
82 unused: Default::default(),
83 })
84 }
85}
86
87impl<'o> ReplyFsInfo<'o> for Statfs {
88 fn info(reply: Reply<'o, Self>, fs_info: &FsInfo) -> Done<'o> {
89 reply.single(&proto::StatfsOut::from(*fs_info))
90 }
91}