11// Copyright (C) Nitrokey GmbH
22// SPDX-License-Identifier: Apache-2.0 or MIT
33
4- use littlefs2:: driver:: Storage as LfsStorage ;
5- use littlefs2:: fs:: { File , Filesystem , OpenOptions } ;
6- use littlefs2:: io:: { SeekFrom , Write } ;
4+ use littlefs2:: fs:: OpenOptions ;
5+ use littlefs2:: io:: SeekFrom ;
76
8- use trussed:: store:: { create_directories, Store } ;
7+ use trussed:: store:: { create_directories, DynFile , DynFilesystem , Store } ;
98use trussed:: types:: { Bytes , Location , Message , Path , PathBuf } ;
109use trussed:: Error ;
1110
@@ -29,8 +28,8 @@ impl From<OpenSeekFrom> for SeekFrom {
2928 }
3029}
3130
32- pub fn fs_read_chunk < Storage : LfsStorage , const N : usize > (
33- fs : & Filesystem < Storage > ,
31+ pub fn fs_read_chunk < const N : usize > (
32+ fs : & dyn DynFilesystem ,
3433 path : & Path ,
3534 pos : OpenSeekFrom ,
3635 length : usize ,
@@ -40,13 +39,14 @@ pub fn fs_read_chunk<Storage: LfsStorage, const N: usize>(
4039 return Err ( Error :: FilesystemReadFailure ) ;
4140 }
4241 contents. resize_default ( length) . unwrap ( ) ;
43- let file_len = File :: open_and_then ( fs, path, |file| {
44- file. seek ( pos. into ( ) ) ?;
45- let read_n = file. read ( & mut contents) ?;
46- contents. truncate ( read_n) ;
47- file. len ( )
48- } )
49- . map_err ( |_| Error :: FilesystemReadFailure ) ?;
42+ let file_len = fs
43+ . open_file_and_then ( path, & mut |file| {
44+ file. seek ( pos. into ( ) ) ?;
45+ let read_n = file. read ( & mut contents) ?;
46+ contents. truncate ( read_n) ;
47+ file. len ( )
48+ } )
49+ . map_err ( |_| Error :: FilesystemReadFailure ) ?;
5050 Ok ( ( contents, file_len) )
5151}
5252
@@ -59,28 +59,24 @@ pub fn read_chunk<const N: usize>(
5959 pos : OpenSeekFrom ,
6060) -> Result < ( Bytes < N > , usize ) , Error > {
6161 debug_now ! ( "reading chunk {},{:?}" , & path, pos) ;
62- match location {
63- Location :: Internal => fs_read_chunk ( store. ifs ( ) , path, pos, N ) ,
64- Location :: External => fs_read_chunk ( store. efs ( ) , path, pos, N ) ,
65- Location :: Volatile => fs_read_chunk ( store. vfs ( ) , path, pos, N ) ,
66- }
62+ fs_read_chunk ( store. fs ( location) , path, pos, N )
6763}
6864
69- pub fn fs_write_chunk < Storage : LfsStorage > (
70- fs : & Filesystem < Storage > ,
65+ pub fn fs_write_chunk (
66+ fs : & dyn DynFilesystem ,
7167 path : & Path ,
7268 contents : & [ u8 ] ,
7369 pos : OpenSeekFrom ,
7470) -> Result < ( ) , Error > {
75- File :: < Storage > :: with_options ( )
76- . read ( true )
77- . write ( true )
78- . open_and_then ( fs , path , |file| {
71+ fs . open_file_with_options_and_then (
72+ & |options| options . read ( true ) . write ( true ) ,
73+ path ,
74+ & mut |file| {
7975 file. seek ( pos. into ( ) ) ?;
8076 file. write_all ( contents)
81- } )
82- . map_err ( |_| Error :: FilesystemReadFailure ) ? ;
83- Ok ( ( ) )
77+ } ,
78+ )
79+ . map_err ( |_| Error :: FilesystemReadFailure )
8480}
8581
8682/// Writes contents to path in location of store.
@@ -93,12 +89,8 @@ pub fn write_chunk(
9389 pos : OpenSeekFrom ,
9490) -> Result < ( ) , Error > {
9591 debug_now ! ( "writing {}" , & path) ;
96- match location {
97- Location :: Internal => fs_write_chunk ( store. ifs ( ) , path, contents, pos) ,
98- Location :: External => fs_write_chunk ( store. efs ( ) , path, contents, pos) ,
99- Location :: Volatile => fs_write_chunk ( store. vfs ( ) , path, contents, pos) ,
100- }
101- . map_err ( |_| Error :: FilesystemWriteFailure )
92+ fs_write_chunk ( store. fs ( location) , path, contents, pos)
93+ . map_err ( |_| Error :: FilesystemWriteFailure )
10294}
10395
10496pub fn move_file (
@@ -116,12 +108,7 @@ pub fn move_file(
116108 to_path
117109 ) ;
118110
119- match to_location {
120- Location :: Internal => create_directories ( store. ifs ( ) , to_path) ,
121- Location :: External => create_directories ( store. efs ( ) , to_path) ,
122- Location :: Volatile => create_directories ( store. vfs ( ) , to_path) ,
123- }
124- . map_err ( |_err| {
111+ create_directories ( store. fs ( to_location) , to_path) . map_err ( |_err| {
125112 error ! ( "Failed to create directories chunks: {:?}" , _err) ;
126113 Error :: FilesystemWriteFailure
127114 } ) ?;
@@ -131,67 +118,29 @@ pub fn move_file(
131118 Error :: FilesystemWriteFailure
132119 } ;
133120 // Fast path for same-filesystem
134- match ( from_location, to_location) {
135- ( Location :: Internal , Location :: Internal ) => {
136- return store. ifs ( ) . rename ( from_path, to_path) . map_err ( on_fail)
137- }
138- ( Location :: External , Location :: External ) => {
139- return store. efs ( ) . rename ( from_path, to_path) . map_err ( on_fail)
140- }
141- ( Location :: Volatile , Location :: Volatile ) => {
142- return store. vfs ( ) . rename ( from_path, to_path) . map_err ( on_fail)
143- }
144- _ => { }
145- }
146-
147- match from_location {
148- Location :: Internal => {
149- move_file_step1 ( store, & * * store. ifs ( ) , from_path, to_location, to_path)
150- }
151- Location :: External => {
152- move_file_step1 ( store, & * * store. efs ( ) , from_path, to_location, to_path)
153- }
154- Location :: Volatile => {
155- move_file_step1 ( store, & * * store. vfs ( ) , from_path, to_location, to_path)
156- }
121+ if from_location == to_location {
122+ return store
123+ . fs ( from_location)
124+ . rename ( from_path, to_path)
125+ . map_err ( on_fail) ;
157126 }
158- }
159127
160- // Separate generic function to avoid having 9 times the same code because the filesystem types are not the same.
161- fn move_file_step1 < S : LfsStorage > (
162- store : impl Store ,
163- from_fs : & Filesystem < S > ,
164- from_path : & Path ,
165- to_location : Location ,
166- to_path : & Path ,
167- ) -> Result < ( ) , Error > {
168- match to_location {
169- Location :: Internal => move_file_step2 ( from_fs, from_path, & * * store. ifs ( ) , to_path) ,
170- Location :: External => move_file_step2 ( from_fs, from_path, & * * store. efs ( ) , to_path) ,
171- Location :: Volatile => move_file_step2 ( from_fs, from_path, & * * store. vfs ( ) , to_path) ,
172- }
173- }
174-
175- // Separate generic function to avoid having 9 times the same code because the filesystem types are not the same.
176- fn move_file_step2 < S1 : LfsStorage , S2 : LfsStorage > (
177- from_fs : & Filesystem < S1 > ,
178- from_path : & Path ,
179- to_fs : & Filesystem < S2 > ,
180- to_path : & Path ,
181- ) -> Result < ( ) , Error > {
182- File :: open_and_then ( from_fs, from_path, |from_file| {
183- File :: create_and_then ( to_fs, to_path, |to_file| copy_file_data ( from_file, to_file) )
184- } )
185- . map_err ( |_err| {
186- error ! ( "Failed to flush chunks: {:?}" , _err) ;
187- Error :: FilesystemWriteFailure
188- } )
128+ store
129+ . fs ( from_location)
130+ . open_file_and_then ( from_path, & mut |from_file| {
131+ let mut options = OpenOptions :: new ( ) ;
132+ options. write ( true ) . create ( true ) . truncate ( true ) ;
133+ store
134+ . fs ( to_location)
135+ . create_file_and_then ( to_path, & mut |to_file| copy_file_data ( from_file, to_file) )
136+ } )
137+ . map_err ( |_err| {
138+ error ! ( "Failed to flush chunks: {:?}" , _err) ;
139+ Error :: FilesystemWriteFailure
140+ } )
189141}
190142
191- fn copy_file_data < S1 : LfsStorage , S2 : LfsStorage > (
192- from : & File < S1 > ,
193- to : & File < S2 > ,
194- ) -> Result < ( ) , littlefs2:: io:: Error > {
143+ fn copy_file_data ( from : & dyn DynFile , to : & dyn DynFile ) -> Result < ( ) , littlefs2:: io:: Error > {
195144 let mut buf = [ 0 ; 1024 ] ;
196145 loop {
197146 let read = from. read ( & mut buf) ?;
@@ -307,26 +256,7 @@ pub fn partial_read_file(
307256 let path = actual_path ( client_id, path) ?;
308257 let offset = u32:: try_from ( offset) . map_err ( |_| Error :: FilesystemReadFailure ) ?;
309258 let pos = OpenSeekFrom :: Start ( offset) ;
310- match location {
311- Location :: Internal => fs_read_chunk ( store. ifs ( ) , & path, pos, length) ,
312- Location :: External => fs_read_chunk ( store. efs ( ) , & path, pos, length) ,
313- Location :: Volatile => fs_read_chunk ( store. vfs ( ) , & path, pos, length) ,
314- }
315- }
316-
317- fn fs_append_file < Storage : LfsStorage > (
318- fs : & Filesystem < Storage > ,
319- path : & Path ,
320- data : & [ u8 ] ,
321- ) -> Result < usize , Error > {
322- OpenOptions :: new ( )
323- . write ( true )
324- . append ( true )
325- . open_and_then ( fs, path, |file| {
326- file. write_all ( data) ?;
327- file. len ( )
328- } )
329- . map_err ( |_| Error :: FilesystemWriteFailure )
259+ fs_read_chunk ( store. fs ( location) , & path, pos, length)
330260}
331261
332262pub fn append_file (
@@ -337,9 +267,15 @@ pub fn append_file(
337267 data : & [ u8 ] ,
338268) -> Result < usize , Error > {
339269 let path = actual_path ( client_id, path) ?;
340- match location {
341- Location :: Internal => fs_append_file ( store. ifs ( ) , & path, data) ,
342- Location :: External => fs_append_file ( store. efs ( ) , & path, data) ,
343- Location :: Volatile => fs_append_file ( store. vfs ( ) , & path, data) ,
344- }
270+ store
271+ . fs ( location)
272+ . open_file_with_options_and_then (
273+ & |options| options. write ( true ) . append ( true ) ,
274+ & path,
275+ & mut |file| {
276+ file. write_all ( data) ?;
277+ file. len ( )
278+ } ,
279+ )
280+ . map_err ( |_| Error :: FilesystemWriteFailure )
345281}
0 commit comments