Skip to content

Commit 3d7e164

Browse files
Use DynFilesystem trait
1 parent 3b9594d commit 3d7e164

File tree

3 files changed

+83
-177
lines changed

3 files changed

+83
-177
lines changed

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,5 +42,5 @@ log-warn = []
4242
log-error = []
4343

4444
[patch.crates-io]
45-
trussed = { git = "https://github.com/trussed-dev/trussed.git", rev = "976372331be2f1b37cab532420cb6c55e0d54473" }
46-
littlefs2 = { git = "https://github.com/trussed-dev/littlefs2.git", rev = "ae57c299312700ca4a3c4437d784a0f4e4f56759" }
45+
trussed = { git = "https://github.com/Nitrokey/trussed.git", branch = "dyn-fs" }
46+
littlefs2 = { git = "https://github.com/Nitrokey/littlefs2.git", branch = "dyn" }

src/manage.rs

Lines changed: 24 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -194,34 +194,19 @@ impl ExtensionImpl<ManageExtension> for StagingBackend {
194194
ManageRequest::FactoryResetDevice(FactoryResetDeviceRequest) => {
195195
let platform = resources.platform();
196196
let store = platform.store();
197-
let ifs = store.ifs();
198-
let efs = store.efs();
199-
let vfs = store.vfs();
200197

201-
ifs.remove_dir_all_where(
202-
path!("/"),
203-
&callback(self.manage.should_preserve_file, Location::Internal),
204-
)
205-
.map_err(|_err| {
206-
debug!("Failed to delete ifs: {_err:?}");
207-
Error::FunctionFailed
208-
})?;
209-
efs.remove_dir_all_where(
210-
path!("/"),
211-
&callback(self.manage.should_preserve_file, Location::External),
212-
)
213-
.map_err(|_err| {
214-
debug!("Failed to delete efs: {_err:?}");
215-
Error::FunctionFailed
216-
})?;
217-
vfs.remove_dir_all_where(
218-
path!("/"),
219-
&callback(self.manage.should_preserve_file, Location::Volatile),
220-
)
221-
.map_err(|_err| {
222-
debug!("Failed to delete vfs: {_err:?}");
223-
Error::FunctionFailed
224-
})?;
198+
for location in [Location::Internal, Location::External, Location::Volatile] {
199+
store
200+
.fs(location)
201+
.remove_dir_all_where(
202+
path!("/"),
203+
&callback(self.manage.should_preserve_file, location),
204+
)
205+
.map_err(|_err| {
206+
debug!("Failed to delete {location:?} fs: {_err:?}");
207+
Error::FunctionFailed
208+
})?;
209+
}
225210
Ok(ManageReply::FactoryResetDevice(FactoryResetDeviceReply))
226211
}
227212
ManageRequest::FactoryResetClient(FactoryResetClientRequest { client }) => {
@@ -234,33 +219,18 @@ impl ExtensionImpl<ManageExtension> for StagingBackend {
234219

235220
let path = path!("/").join(client);
236221

237-
let ifs = store.ifs();
238-
let efs = store.efs();
239-
let vfs = store.vfs();
240-
ifs.remove_dir_all_where(
241-
&path,
242-
&callback(self.manage.should_preserve_file, Location::Internal),
243-
)
244-
.map_err(|_err| {
245-
debug!("Failed to delete ifs: {_err:?}");
246-
Error::FunctionFailed
247-
})?;
248-
efs.remove_dir_all_where(
249-
&path,
250-
&callback(self.manage.should_preserve_file, Location::External),
251-
)
252-
.map_err(|_err| {
253-
debug!("Failed to delete efs: {_err:?}");
254-
Error::FunctionFailed
255-
})?;
256-
vfs.remove_dir_all_where(
257-
&path,
258-
&callback(self.manage.should_preserve_file, Location::Volatile),
259-
)
260-
.map_err(|_err| {
261-
debug!("Failed to delete vfs: {_err:?}");
262-
Error::FunctionFailed
263-
})?;
222+
for location in [Location::Internal, Location::External, Location::Volatile] {
223+
store
224+
.fs(location)
225+
.remove_dir_all_where(
226+
&path,
227+
&callback(self.manage.should_preserve_file, location),
228+
)
229+
.map_err(|_err| {
230+
debug!("Failed to delete {location:?} fs: {_err:?}");
231+
Error::FunctionFailed
232+
})?;
233+
}
264234
Ok(ManageReply::FactoryResetClient(FactoryResetClientReply))
265235
}
266236
}

src/streaming/store.rs

Lines changed: 57 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
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};
98
use trussed::types::{Bytes, Location, Message, Path, PathBuf};
109
use 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

10496
pub 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

332262
pub 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

Comments
 (0)