1use std::collections::{BTreeSet, VecDeque};
2use std::ffi::{OsStr, OsString};
3use std::sync::Arc;
4
5use tokio::sync::RwLock;
6
7use crate::DirEntry;
8
9#[async_trait::async_trait]
16pub trait Filesystem {
17 type Error: Into<crate::error::Error>;
18 async fn destroy(&mut self) -> Result<(), Self::Error> {
20 Ok(())
21 }
22 async fn lookup(&self, parent: u64, name: &OsStr) -> Result<fuser::FileAttr, Self::Error>;
24 async fn open(&self, _ino: u64, _flags: i32) -> Result<u64, Self::Error> {
26 Ok(0)
27 }
28 async fn release(&self, _ino: u64, _fh: u64) -> Result<(), Self::Error> {
30 Ok(())
31 }
32 async fn getattr(&self, _ino: u64) -> Result<fuser::FileAttr, Self::Error>;
34 async fn setattr(
36 &mut self,
37 ino: u64,
38 size: Option<u64>,
39 ) -> Result<fuser::FileAttr, Self::Error>;
40 async fn readdir(
47 &self,
48 ino: u64,
49 offset: u64,
50 ) -> Result<Box<dyn Iterator<Item = DirEntry> + Send + Sync + '_>, Self::Error>;
51 async fn read(
53 &self,
54 ino: u64,
55 fh: u64,
56 offset: i64,
57 size: u32,
58 ) -> Result<bytes::Bytes, Self::Error>;
59 async fn write(
61 &self,
62 ino: u64,
63 fh: u64,
64 data: bytes::Bytes,
65 offset: i64,
66 ) -> Result<u32, Self::Error>;
67 async fn create(
69 &mut self,
70 parent: u64,
71 name: OsString,
72 mode: u32,
73 umask: u32,
74 flags: i32,
75 ) -> Result<(fuser::FileAttr, u64), Self::Error>;
76 async fn mkdir(&mut self, parent: u64, name: OsString) -> Result<fuser::FileAttr, Self::Error>;
78 async fn inodes(&self) -> Result<BTreeSet<u64>, Self::Error> {
83 let mut inodes = BTreeSet::from([fuser::FUSE_ROOT_ID]);
84 let mut queue = VecDeque::from([fuser::FUSE_ROOT_ID]);
85 while let Some(ino) = queue.pop_front() {
86 for entry in self.readdir(ino, 0).await? {
87 inodes.insert(entry.inode);
88 if entry.file_type == fuser::FileType::Directory {
89 queue.push_back(entry.inode);
90 }
91 }
92 }
93 Ok(inodes)
94 }
95}
96#[async_trait::async_trait]
97impl<T: Filesystem + Send + Sync + 'static> Filesystem for Arc<RwLock<T>> {
98 type Error = T::Error;
99 async fn destroy(&mut self) -> Result<(), Self::Error> {
100 let mut x = self.as_ref().write().await;
101 x.destroy().await
102 }
103 async fn lookup(&self, parent: u64, name: &OsStr) -> Result<fuser::FileAttr, Self::Error> {
104 let x = self.as_ref().read().await;
105 x.lookup(parent, name).await
106 }
107 async fn open(&self, ino: u64, flags: i32) -> Result<u64, Self::Error> {
108 let x = self.as_ref().read().await;
109 x.open(ino, flags).await
110 }
111 async fn release(&self, ino: u64, fh: u64) -> Result<(), Self::Error> {
112 let x = self.as_ref().read().await;
113 x.release(ino, fh).await
114 }
115 async fn getattr(&self, ino: u64) -> Result<fuser::FileAttr, Self::Error> {
116 let x = self.as_ref().read().await;
117 x.getattr(ino).await
118 }
119 async fn setattr(
120 &mut self,
121 ino: u64,
122 size: Option<u64>,
123 ) -> Result<fuser::FileAttr, Self::Error> {
124 let mut x = self.as_ref().write().await;
125 x.setattr(ino, size).await
126 }
127 async fn readdir(
128 &self,
129 ino: u64,
130 offset: u64,
131 ) -> Result<Box<dyn Iterator<Item = DirEntry> + Send + Sync + '_>, Self::Error> {
132 let x = self.as_ref().read().await;
133 let dir = x.readdir(ino, offset).await?;
134 Ok(Box::new(dir.collect::<Vec<_>>().into_iter()))
136 }
137 async fn read(
138 &self,
139 ino: u64,
140 fh: u64,
141 offset: i64,
142 size: u32,
143 ) -> Result<bytes::Bytes, Self::Error> {
144 let x = self.as_ref().read().await;
145 x.read(ino, fh, offset, size).await
146 }
147 async fn write(
148 &self,
149 ino: u64,
150 fh: u64,
151 data: bytes::Bytes,
152 offset: i64,
153 ) -> Result<u32, Self::Error> {
154 let x = self.as_ref().read().await;
155 x.write(ino, fh, data, offset).await
156 }
157 async fn create(
158 &mut self,
159 parent: u64,
160 name: OsString,
161 mode: u32,
162 umask: u32,
163 flags: i32,
164 ) -> Result<(fuser::FileAttr, u64), Self::Error> {
165 let mut x = self.as_ref().write().await;
166 x.create(parent, name, mode, umask, flags).await
167 }
168 async fn mkdir(&mut self, parent: u64, name: OsString) -> Result<fuser::FileAttr, Self::Error> {
169 let mut x = self.as_ref().write().await;
170 x.mkdir(parent, name).await
171 }
172 async fn inodes(&self) -> Result<BTreeSet<u64>, Self::Error> {
173 let x = self.as_ref().read().await;
174 x.inodes().await
175 }
176}