17
17
* under the License.
18
18
*/
19
19
use crate :: filesystem:: {
20
- FileReader , FileStat , FileWriter , OpenedFile , PathFileSystem , Result ,
20
+ FileReader , FileStat , FileWriter , OpenFileFlags , OpenedFile , PathFileSystem , Result ,
21
21
} ;
22
+ use crate :: filesystem_metadata:: DefaultFileSystemMetadata ;
23
+ use crate :: utils:: join_file_path;
22
24
use async_trait:: async_trait;
25
+ use bytes:: Bytes ;
23
26
use dashmap:: DashMap ;
27
+ use fuse3:: FileType :: { Directory , RegularFile } ;
24
28
use fuse3:: { Errno , FileType } ;
25
29
use regex:: Regex ;
26
30
use std:: collections:: BTreeMap ;
27
31
use std:: sync:: { Arc , Mutex , RwLock } ;
28
- use bytes:: Bytes ;
29
- use crate :: utils:: join_file_path;
30
32
31
33
// MemoryFileSystem is a simple in-memory filesystem implementation
32
34
// It is used for testing purposes
33
- pub ( crate ) struct MemoryFileSystem {
34
- // file_map is a map of file stats
35
- file_map : RwLock < BTreeMap < String , FileStat > > ,
36
35
37
- // file_data_map is a map of file data
38
- file_data_map : DashMap < String , Arc < Mutex < Vec < u8 > > > > ,
36
+ struct MemoryFile {
37
+ kind : FileType ,
38
+ data : Arc < Mutex < Vec < u8 > > > ,
39
+ }
40
+
41
+ pub ( crate ) struct MemoryFileSystem {
42
+ // file_map is a map of file name to file size
43
+ file_map : RwLock < BTreeMap < String , MemoryFile > > ,
39
44
}
40
45
41
46
impl MemoryFileSystem {
42
47
pub fn new ( ) -> Self {
43
48
Self {
44
49
file_map : RwLock :: new ( Default :: default ( ) ) ,
45
- file_data_map : Default :: default ( ) ,
46
50
}
47
51
}
48
52
49
53
pub fn init ( & self ) { }
54
+
55
+ fn create_file_stat ( & self , path : & str , file : & MemoryFile ) -> FileStat {
56
+ match file. kind {
57
+ Directory => FileStat :: new_dir_with_path ( path) ,
58
+ _ => FileStat :: new_file_with_path ( path, file. data . lock ( ) . unwrap ( ) . len ( ) as u64 ) ,
59
+ }
60
+ }
50
61
}
51
62
52
63
#[ async_trait]
53
64
impl PathFileSystem for MemoryFileSystem {
54
- async fn init ( & self ) { }
65
+ async fn init ( & self ) {
66
+ let root = MemoryFile {
67
+ kind : Directory ,
68
+ data : Arc :: new ( Mutex :: new ( Vec :: new ( ) ) ) ,
69
+ } ;
70
+ self . file_map . write ( ) . unwrap ( ) . insert ( "" . to_string ( ) , root) ;
71
+
72
+ let meta = MemoryFile {
73
+ kind : RegularFile ,
74
+ data : Arc :: new ( Mutex :: new ( Vec :: new ( ) ) ) ,
75
+ } ;
76
+ self . file_map . write ( ) . unwrap ( ) . insert (
77
+ DefaultFileSystemMetadata :: FS_META_FILE_NAME . to_string ( ) ,
78
+ meta,
79
+ ) ;
80
+ }
55
81
56
82
async fn stat ( & self , name : & str ) -> Result < FileStat > {
57
83
self . file_map
58
84
. read ( )
59
85
. unwrap ( )
60
86
. get ( name)
61
- . map ( |x| x . clone ( ) )
87
+ . map ( |x| self . create_file_stat ( name , x ) )
62
88
. ok_or ( Errno :: from ( libc:: ENOENT ) )
63
89
}
64
90
@@ -72,66 +98,84 @@ impl PathFileSystem for MemoryFileSystem {
72
98
let results: Vec < FileStat > = file_map
73
99
. iter ( )
74
100
. filter ( |x| dir_child_reg_expr ( name) . is_match ( x. 0 ) )
75
- . map ( |( _ , v) | v . clone ( ) )
101
+ . map ( |( k , v) | self . create_file_stat ( k , v ) )
76
102
. collect ( ) ;
77
103
78
104
Ok ( results)
79
105
}
80
106
81
- async fn open_file ( & self , name : & str , flags : u32 ) -> Result < OpenedFile > {
107
+ async fn open_file ( & self , name : & str , flags : OpenFileFlags ) -> Result < OpenedFile > {
82
108
let file_stat = self . stat ( name) . await ?;
83
109
let mut file = OpenedFile :: new ( file_stat. clone ( ) ) ;
84
110
match file. file_stat . kind {
85
- FileType :: Directory => {
86
- Ok ( file)
87
- }
88
- FileType :: RegularFile => {
89
- let data = self . file_data_map . get ( & file. file_stat . path ) . unwrap ( ) . value ( ) . clone ( ) ;
90
- file. reader = Some ( Box :: new ( MemoryFileReader {
91
- data : data. clone ( ) ,
92
- } ) ) ;
93
- file. writer = Some ( Box :: new ( MemoryFileWriter {
94
- data : data,
95
- } ) ) ;
111
+ Directory => Ok ( file) ,
112
+ RegularFile => {
113
+ let data = self
114
+ . file_map
115
+ . read ( )
116
+ . unwrap ( )
117
+ . get ( & file. file_stat . path )
118
+ . unwrap ( )
119
+ . data
120
+ . clone ( ) ;
121
+ file. reader = Some ( Box :: new ( MemoryFileReader { data : data. clone ( ) } ) ) ;
122
+ file. writer = Some ( Box :: new ( MemoryFileWriter { data : data } ) ) ;
96
123
Ok ( file)
97
124
}
98
125
_ => Err ( Errno :: from ( libc:: EBADF ) ) ,
99
126
}
100
127
}
101
128
102
- async fn create_file ( & self , parent : & str , name : & str ) -> Result < OpenedFile > {
103
- let mut file_map = self . file_map . read ( ) . unwrap ( ) ;
104
- if file_map. contains_key ( & join_file_path ( parent, name) ) {
105
- return Err ( Errno :: from ( libc:: EEXIST ) ) ;
106
- }
129
+ async fn create_file (
130
+ & self ,
131
+ parent : & str ,
132
+ name : & str ,
133
+ flags : OpenFileFlags ,
134
+ ) -> Result < OpenedFile > {
135
+ {
136
+ let file_map = self . file_map . read ( ) . unwrap ( ) ;
137
+ if file_map. contains_key ( & join_file_path ( parent, name) ) {
138
+ return Err ( Errno :: from ( libc:: EEXIST ) ) ;
139
+ }
140
+ } ;
107
141
108
142
let mut file = OpenedFile :: new ( FileStat :: new_file ( parent, name, 0 ) ) ;
109
143
110
- self . file_data_map
111
- . insert ( file. file_stat . path . clone ( ) , Arc :: new ( Mutex :: new ( Vec :: new ( ) ) ) ) ;
112
- let data = self . file_data_map . get ( & file. file_stat . path ) . unwrap ( ) . value ( ) . clone ( ) ;
113
- file. reader = Some ( Box :: new ( MemoryFileReader {
114
- data : data. clone ( ) ,
115
- } ) ) ;
116
- file. writer = Some ( Box :: new ( MemoryFileWriter {
117
- data : data,
118
- } ) ) ;
144
+ let data = Arc :: new ( Mutex :: new ( Vec :: new ( ) ) ) ;
145
+ self . file_map . write ( ) . unwrap ( ) . insert (
146
+ file. file_stat . path . clone ( ) ,
147
+ MemoryFile {
148
+ kind : RegularFile ,
149
+ data : data. clone ( ) ,
150
+ } ,
151
+ ) ;
152
+ file. reader = Some ( Box :: new ( MemoryFileReader { data : data. clone ( ) } ) ) ;
153
+ file. writer = Some ( Box :: new ( MemoryFileWriter { data : data } ) ) ;
154
+
119
155
Ok ( file)
120
156
}
121
157
122
158
async fn create_dir ( & self , parent : & str , name : & str ) -> Result < OpenedFile > {
123
- let mut file_map = self . file_map . read ( ) . unwrap ( ) ;
124
- if file_map. contains_key ( & join_file_path ( parent, name) ) {
125
- return Err ( Errno :: from ( libc:: EEXIST ) ) ;
159
+ {
160
+ let mut file_map = self . file_map . read ( ) . unwrap ( ) ;
161
+ if file_map. contains_key ( & join_file_path ( parent, name) ) {
162
+ return Err ( Errno :: from ( libc:: EEXIST ) ) ;
163
+ }
126
164
}
127
165
128
166
let file = OpenedFile :: new ( FileStat :: new_dir ( parent, name) ) ;
167
+ self . file_map . write ( ) . unwrap ( ) . insert (
168
+ file. file_stat . path . clone ( ) ,
169
+ MemoryFile {
170
+ kind : Directory ,
171
+ data : Arc :: new ( Mutex :: new ( Vec :: new ( ) ) ) ,
172
+ } ,
173
+ ) ;
174
+
129
175
Ok ( file)
130
176
}
131
177
132
178
async fn set_attr ( & self , name : & str , file_stat : & FileStat , flush : bool ) -> Result < ( ) > {
133
- let mut file_map = self . file_map . write ( ) . unwrap ( ) ;
134
- file_map. insert ( name. to_string ( ) , file_stat. clone ( ) ) ;
135
179
Ok ( ( ) )
136
180
}
137
181
@@ -165,7 +209,6 @@ pub(crate) struct MemoryFileReader {
165
209
166
210
#[ async_trait]
167
211
impl FileReader for MemoryFileReader {
168
-
169
212
async fn read ( & mut self , offset : u64 , size : u32 ) -> Result < Bytes > {
170
213
let v = self . data . lock ( ) . unwrap ( ) ;
171
214
let start = offset as usize ;
@@ -183,7 +226,6 @@ pub(crate) struct MemoryFileWriter {
183
226
184
227
#[ async_trait]
185
228
impl FileWriter for MemoryFileWriter {
186
-
187
229
async fn write ( & mut self , offset : u64 , data : & [ u8 ] ) -> Result < u32 > {
188
230
let mut v = self . data . lock ( ) . unwrap ( ) ;
189
231
let start = offset as usize ;
0 commit comments