1use super::traits::{ReplyOk, RequestHandle};
2use crate::{
3 io::{Ino, Stat},
4 proto,
5 sealed::Sealed,
6 Done, Operation, Reply, Request,
7};
8
9pub enum Forget {}
10pub enum Getattr {}
11pub enum Bmap {}
12
13pub trait RequestForget<'o>: Operation<'o> {
14 fn forget_list<'a>(request: &'a Request<'o, Self>) -> ForgetList<'a>;
15}
16
17pub trait RequestBlock<'o>: Operation<'o> {
18 fn block(request: &Request<'o, Self>) -> u64;
19 fn block_size(request: &Request<'o, Self>) -> u32;
20}
21
22pub trait ReplyStat<'o>: Operation<'o> {
23 fn stat(reply: Reply<'o, Self>, inode: &impl Stat) -> Done<'o>;
24}
25
26pub trait ReplyBlock<'o>: Operation<'o> {
27 fn block(reply: Reply<'o, Self>, block: u64) -> Done<'o>;
28}
29
30pub enum ForgetList<'a> {
31 Single(Option<(Ino, u64)>),
32 Batch(std::slice::Iter<'a, proto::ForgetOne>),
33}
34
35impl Sealed for Forget {}
36impl Sealed for Getattr {}
37impl Sealed for Bmap {}
38
39impl<'o> Operation<'o> for Forget {
40 type RequestBody = proto::OpcodeSelect<
41 (&'o proto::BatchForgetIn, &'o [proto::ForgetOne]),
42 &'o proto::ForgetIn,
43 { proto::Opcode::BatchForget as u32 },
44 >;
45
46 type ReplyState = ();
47}
48
49impl<'o> Operation<'o> for Getattr {
50 type RequestBody = &'o proto::GetattrIn;
51 type ReplyState = ();
52}
53
54impl<'o> Operation<'o> for Bmap {
55 type RequestBody = &'o proto::BmapIn;
56 type ReplyState = ();
57}
58
59impl<'o> RequestForget<'o> for Forget {
60 fn forget_list<'a>(request: &'a Request<'o, Self>) -> ForgetList<'a> {
61 use {proto::OpcodeSelect::*, ForgetList::*};
62
63 impl Iterator for ForgetList<'_> {
64 type Item = (Ino, u64);
65
66 fn next(&mut self) -> Option<Self::Item> {
67 match self {
68 Single(single) => single.take(),
69 Batch(batch) => {
70 let forget = batch.next()?;
71 Some((Ino(forget.ino), forget.nlookup))
72 }
73 }
74 }
75 }
76
77 match request.body {
78 Match((_, slice)) => Batch(slice.iter()),
79 Alt(single) => Single(Some((request.ino(), single.nlookup))),
80 }
81 }
82}
83
84impl<'o> ReplyOk<'o> for Forget {
85 fn ok(_reply: Reply<'o, Self>) -> Done<'o> {
86 Done::new()
88 }
89}
90
91impl<'o> RequestHandle<'o> for Getattr {
92 fn handle(request: &Request<'o, Self>) -> u64 {
93 request.body.fh
94 }
95}
96
97impl<'o> ReplyStat<'o> for Getattr {
98 fn stat(reply: Reply<'o, Self>, inode: &impl Stat) -> Done<'o> {
99 let (attrs, ttl) = inode.attrs();
100 let attrs = attrs.finish(inode);
101
102 reply.single(&proto::AttrOut {
103 attr_valid: ttl.seconds(),
104 attr_valid_nsec: ttl.nanoseconds(),
105 dummy: Default::default(),
106 attr: attrs,
107 })
108 }
109}
110
111impl<'o> RequestBlock<'o> for Bmap {
112 fn block(request: &Request<'o, Self>) -> u64 {
113 request.body.block
114 }
115
116 fn block_size(request: &Request<'o, Self>) -> u32 {
117 request.body.block_size
118 }
119}
120
121impl<'o> ReplyBlock<'o> for Bmap {
122 fn block(reply: Reply<'o, Self>, block: u64) -> Done<'o> {
123 reply.single(&proto::BmapOut { block })
124 }
125}