From f2546041b13fec1da7db45cbf88777fe037d986a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sosth=C3=A8ne=20Gu=C3=A9don?= Date: Mon, 13 Mar 2023 15:57:39 +0100 Subject: [PATCH 1/5] Use tell and seek to improve filesystem iteration efficiency --- Cargo.toml | 4 +++ src/store/filestore.rs | 65 +++++++++++++++++++++--------------------- 2 files changed, 37 insertions(+), 32 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index ffa0ad4f46d..fb4c8ac1aa4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -124,3 +124,7 @@ test-attestation-cert-ids = [] [package.metadata.docs.rs] features = ["serde-extensions", "virt"] rustdoc-args = ["--cfg", "docsrs"] + +[patch.crates-io] +littlefs2-sys = { git = "https://github.com/sosthene-nitrokey/littlefs2-sys.git", branch = "update" } +littlefs2 = { git = "https://github.com/sosthene-nitrokey/littlefs2.git", branch = "iter-optimization" } diff --git a/src/store/filestore.rs b/src/store/filestore.rs index c093f3b5086..b096de571a4 100644 --- a/src/store/filestore.rs +++ b/src/store/filestore.rs @@ -11,19 +11,19 @@ use littlefs2::path; pub struct ReadDirState { real_dir: PathBuf, location: Location, - last: usize, + position: DirIterationTell, } #[derive(Clone)] pub struct ReadDirFilesState { real_dir: PathBuf, - last: usize, + position: DirIterationTell, location: Location, user_attribute: Option, } use littlefs2::{ - fs::{DirEntry, Metadata}, + fs::{DirEntry, DirIterationTell, Metadata}, path::{Path, PathBuf}, }; @@ -151,18 +151,18 @@ impl ClientFilestore { let dir = self.actual_path(clients_dir)?; Ok(fs - .read_dir_and_then(&dir, |it| { + .read_dir_and_then(&dir, |mut it| { // this is an iterator with Item = (usize, Result) - it.enumerate() + (&mut it) // skip over `.` and `..` .skip(2) // todo: try ?-ing out of this (the API matches std::fs, where read/write errors // can occur during operation) // // Option> -> ?? - .map(|(i, entry)| (i, entry.unwrap())) + .map(Result::unwrap) // if there is a "not_before" entry, skip all entries before it. - .find(|(_, entry)| { + .find(|entry| { if let Some(not_before) = not_before { entry.file_name() == not_before.as_ref() } else { @@ -172,10 +172,10 @@ impl ClientFilestore { // if there is an entry, construct the state that needs storing out of it, // remove the prefix from the entry's path to not leak implementation details to // the client, and return both the entry and the state - .map(|(i, mut entry)| { + .map(|mut entry| { let read_dir_state = ReadDirState { real_dir: dir.clone(), - last: i, + position: it.tell().unwrap(), location, }; let entry_client_path = self.client_path(entry.path()); @@ -203,24 +203,25 @@ impl ClientFilestore { ) -> Result> { let ReadDirState { real_dir, - last, + position, location, } = state; // all we want to do here is skip just past the previously found entry // in the directory iterator, then return it (plus state to continue on next call) Ok(fs - .read_dir_and_then(&real_dir, |it| { + .read_dir_and_then(&real_dir, |mut it| { // skip over previous - it.enumerate() - .nth(last + 1) + it.seek(position)?; + (&mut it) + .next() // entry is still a Result :/ (see question in `read_dir_first`) - .map(|(i, entry)| (i, entry.unwrap())) + .map(Result::unwrap) // convert Option into Result, again because `read_dir_and_then` expects this - .map(|(i, mut entry)| { + .map(|mut entry| { let read_dir_state = ReadDirState { real_dir: real_dir.clone(), - last: i, + position: it.tell().unwrap(), location, }; @@ -243,18 +244,18 @@ impl ClientFilestore { let dir = self.actual_path(clients_dir)?; Ok(fs - .read_dir_and_then(&dir, |it| { + .read_dir_and_then(&dir, |mut it| { // this is an iterator with Item = (usize, Result) - it.enumerate() + (&mut it) // todo: try ?-ing out of this (the API matches std::fs, where read/write errors // can occur during operation) // // Option> -> ?? - .map(|(i, entry)| (i, entry.unwrap())) + .map(Result::unwrap) // skip over directories (including `.` and `..`) - .filter(|(_, entry)| entry.file_type().is_file()) + .filter(|entry| entry.file_type().is_file()) // take first entry that meets requirements - .find(|(_, entry)| { + .find(|entry| { if let Some(user_attribute) = user_attribute.as_ref() { let mut path = dir.clone(); path.push(entry.file_name()); @@ -274,10 +275,10 @@ impl ClientFilestore { // if there is an entry, construct the state that needs storing out of it, // and return the file's contents. // the client, and return both the entry and the state - .map(|(i, entry)| { + .map(|entry| { let read_dir_files_state = ReadDirFilesState { real_dir: dir.clone(), - last: i, + position: it.tell().unwrap(), location, user_attribute, }; @@ -301,7 +302,7 @@ impl ClientFilestore { ) -> Result, ReadDirFilesState)>> { let ReadDirFilesState { real_dir, - last, + position, location, user_attribute, } = state; @@ -309,16 +310,16 @@ impl ClientFilestore { // all we want to do here is skip just past the previously found entry // in the directory iterator, then return it (plus state to continue on next call) Ok(fs - .read_dir_and_then(&real_dir, |it| { + .read_dir_and_then(&real_dir, |mut it| { // skip over previous - it.enumerate() - .skip(last + 1) + it.seek(position)?; + (&mut it) // entry is still a Result :/ (see question in `read_dir_first`) - .map(|(i, entry)| (i, entry.unwrap())) + .map(Result::unwrap) // skip over directories (including `.` and `..`) - .filter(|(_, entry)| entry.file_type().is_file()) + .filter(|entry| entry.file_type().is_file()) // take first entry that meets requirements - .find(|(_, entry)| { + .find(|entry| { if let Some(user_attribute) = user_attribute.as_ref() { let mut path = real_dir.clone(); path.push(entry.file_name()); @@ -334,10 +335,10 @@ impl ClientFilestore { true } }) - .map(|(i, entry)| { + .map(|entry| { let read_dir_files_state = ReadDirFilesState { real_dir: real_dir.clone(), - last: i, + position: it.tell().unwrap(), location, user_attribute, }; From 8c31c1bf41af8da78c96a8788dcc787c19aaff8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sosth=C3=A8ne=20Gu=C3=A9don?= Date: Mon, 13 Mar 2023 17:49:39 +0100 Subject: [PATCH 2/5] Add ReadDir(Files)Nth API call, which allows skipping files (useful for resuming iteration) --- src/api.rs | 19 ++++++++ src/service.rs | 28 ++++++++++++ src/store/filestore.rs | 101 +++++++++++++++++++++++++++++++++++++---- 3 files changed, 140 insertions(+), 8 deletions(-) diff --git a/src/api.rs b/src/api.rs index 146063aed20..a586564c135 100644 --- a/src/api.rs +++ b/src/api.rs @@ -41,6 +41,7 @@ generate_enums! { Hash: 12 // TODO: add ReadDir{First,Next}, not loading data, if needed for efficiency ReadDirFilesFirst: 13 + ReadDirFilesNth: 31 ReadDirFilesNext: 14 ReadFile: 15 Metadata: 26 @@ -63,6 +64,7 @@ generate_enums! { // // CreateDir, <-- implied by WriteFile ReadDirFirst: 31 // <-- gets Option to restrict to just dir/file DirEntries, + ReadDirNth: 31 ReadDirNext: 32 // <-- gets Option to restrict to just dir/file DirEntries, // // returns simplified Metadata // // ReadDirFilesFirst: 23 // <-- returns contents @@ -229,6 +231,12 @@ pub mod request { - dir: PathBuf - user_attribute: Option + ReadDirFilesNth: + - location: Location + - dir: PathBuf + - start_at: usize + - user_attribute: Option + ReadDirFilesNext: ReadDirFirst: @@ -236,6 +244,11 @@ pub mod request { - dir: PathBuf - not_before_filename: Option + ReadDirNth: + - location: Location + - dir: PathBuf + - start_at: usize + ReadDirNext: ReadFile: @@ -419,12 +432,18 @@ pub mod reply { ReadDirFilesFirst: - data: Option + ReadDirFilesNth: + - data: Option + ReadDirFilesNext: - data: Option ReadDirFirst: - entry: Option + ReadDirNth: + - data: Option + ReadDirNext: - entry: Option diff --git a/src/service.rs b/src/service.rs index 1a923b3f357..f5a86d073ea 100644 --- a/src/service.rs +++ b/src/service.rs @@ -355,6 +355,20 @@ impl ServiceResources

{ }; Ok(Reply::ReadDirFirst(reply::ReadDirFirst { entry: maybe_entry } )) } + Request::ReadDirNth(request) => { + let maybe_entry = match filestore.read_dir_nth(&request.dir, request.location, request.start_at)? { + Some((entry, read_dir_state)) => { + ctx.read_dir_state = Some(read_dir_state); + Some(entry) + } + None => { + ctx.read_dir_state = None; + None + + } + }; + Ok(Reply::ReadDirFirst(reply::ReadDirFirst { entry: maybe_entry } )) + } Request::ReadDirNext(_request) => { // ensure next call has nothing to work with, unless we store state again @@ -393,6 +407,20 @@ impl ServiceResources

{ Ok(Reply::ReadDirFilesFirst(reply::ReadDirFilesFirst { data: maybe_data } )) } + Request::ReadDirFilesNth(request) => { + let maybe_data = match filestore.read_dir_files_nth(&request.dir, request.location, request.start_at, request.user_attribute.clone())? { + Some((data, state)) => { + ctx.read_dir_files_state = Some(state); + data + } + None => { + ctx.read_dir_files_state = None; + None + } + }; + Ok(Reply::ReadDirFilesFirst(reply::ReadDirFilesFirst { data: maybe_data } )) + } + Request::ReadDirFilesNext(_request) => { let read_dir_files_state = ctx.read_dir_files_state.take(); diff --git a/src/store/filestore.rs b/src/store/filestore.rs index b096de571a4..83f046420dc 100644 --- a/src/store/filestore.rs +++ b/src/store/filestore.rs @@ -96,6 +96,19 @@ pub trait Filestore { filename: &Path, ) -> Result>; + /// Iterate over entries of a directory (both file and directory entries). + /// + /// This function is modeled after `std::fs::read_dir`, within the limitations of our setup. + /// + /// In case an entry was found, the returned option also contains state, so the expected + /// call to `read_dir_next` can resume operation. + fn read_dir_nth( + &mut self, + dir: &PathBuf, + location: Location, + start_at: usize, + ) -> Result>; + /// Iterate over entries of a directory (both file and directory entries). /// /// This function is modeled after `std::fs::read_dir`, within the limitations of our setup. @@ -132,6 +145,21 @@ pub trait Filestore { user_attribute: Option, ) -> Result, ReadDirFilesState)>>; + /// Iterate over contents of files inside a directory. + /// + /// This has no equivalent in `std::fs`, it is an optimization to avoid duplicate + /// calls and a more complicated state machine (interspersing read_dir_first/next calls + /// with some sort of "fetch data"). + /// + /// Additionally, files may optionally be filtered via attributes. + fn read_dir_files_nth( + &mut self, + clients_dir: &PathBuf, + location: Location, + start_at: usize, + user_attribute: Option, + ) -> Result, ReadDirFilesState)>>; + /// Continuation of `read_dir_files_first`. fn read_dir_files_next( &mut self, @@ -146,6 +174,7 @@ impl ClientFilestore { clients_dir: &Path, location: Location, not_before: Option<&Path>, + start_at: usize, fs: &'static Fs, ) -> Result> { let dir = self.actual_path(clients_dir)?; @@ -155,7 +184,7 @@ impl ClientFilestore { // this is an iterator with Item = (usize, Result) (&mut it) // skip over `.` and `..` - .skip(2) + .skip(2 + start_at) // todo: try ?-ing out of this (the API matches std::fs, where read/write errors // can occur during operation) // @@ -239,6 +268,7 @@ impl ClientFilestore { clients_dir: &Path, location: Location, user_attribute: Option, + start_at: usize, fs: &'static Fs, ) -> Result, ReadDirFilesState)>> { let dir = self.actual_path(clients_dir)?; @@ -254,8 +284,7 @@ impl ClientFilestore { .map(Result::unwrap) // skip over directories (including `.` and `..`) .filter(|entry| entry.file_type().is_file()) - // take first entry that meets requirements - .find(|entry| { + .filter(|entry| { if let Some(user_attribute) = user_attribute.as_ref() { let mut path = dir.clone(); path.push(entry.file_name()); @@ -264,14 +293,16 @@ impl ClientFilestore { .unwrap(); if let Some(attribute) = attribute { - user_attribute == attribute.data() + user_attribute != attribute.data() } else { - false + true } } else { true } }) + // take nth entry that meets requirements + .nth(start_at) // if there is an entry, construct the state that needs storing out of it, // and return the file's contents. // the client, and return both the entry and the state @@ -421,13 +452,32 @@ impl Filestore for ClientFilestore { ) -> Result> { match location { Location::Internal => { - self.read_dir_first_impl(clients_dir, location, not_before, self.store.ifs()) + self.read_dir_first_impl(clients_dir, location, not_before, 0, self.store.ifs()) + } + Location::External => { + self.read_dir_first_impl(clients_dir, location, not_before, 0, self.store.efs()) + } + Location::Volatile => { + self.read_dir_first_impl(clients_dir, location, not_before, 0, self.store.vfs()) + } + } + } + + fn read_dir_nth( + &mut self, + clients_dir: &PathBuf, + location: Location, + start_at: usize, + ) -> Result> { + match location { + Location::Internal => { + self.read_dir_first_impl(clients_dir, location, None, start_at, self.store.ifs()) } Location::External => { - self.read_dir_first_impl(clients_dir, location, not_before, self.store.efs()) + self.read_dir_first_impl(clients_dir, location, None, start_at, self.store.efs()) } Location::Volatile => { - self.read_dir_first_impl(clients_dir, location, not_before, self.store.vfs()) + self.read_dir_first_impl(clients_dir, location, None, start_at, self.store.vfs()) } } } @@ -451,18 +501,53 @@ impl Filestore for ClientFilestore { clients_dir, location, user_attribute, + 0, + self.store.ifs(), + ), + Location::External => self.read_dir_files_first_impl( + clients_dir, + location, + user_attribute, + 0, + self.store.efs(), + ), + Location::Volatile => self.read_dir_files_first_impl( + clients_dir, + location, + user_attribute, + 0, + self.store.vfs(), + ), + } + } + + fn read_dir_files_nth( + &mut self, + clients_dir: &PathBuf, + location: Location, + start_at: usize, + user_attribute: Option, + ) -> Result, ReadDirFilesState)>> { + match location { + Location::Internal => self.read_dir_files_first_impl( + clients_dir, + location, + user_attribute, + start_at, self.store.ifs(), ), Location::External => self.read_dir_files_first_impl( clients_dir, location, user_attribute, + start_at, self.store.efs(), ), Location::Volatile => self.read_dir_files_first_impl( clients_dir, location, user_attribute, + start_at, self.store.vfs(), ), } From a3955546e831d09b2633fce0c3892f08ac392b71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sosth=C3=A8ne=20Gu=C3=A9don?= Date: Tue, 14 Mar 2023 10:36:09 +0100 Subject: [PATCH 3/5] Expose enhanced iteration syscall to the client and test them --- src/api.rs | 6 ++-- src/api/macros.rs | 6 ++-- src/client.rs | 28 +++++++++++++++++ src/service.rs | 4 +-- src/store/filestore.rs | 4 +-- tests/filesystem.rs | 70 ++++++++++++++++++++++++++---------------- 6 files changed, 83 insertions(+), 35 deletions(-) diff --git a/src/api.rs b/src/api.rs index a586564c135..c9d2ef64e58 100644 --- a/src/api.rs +++ b/src/api.rs @@ -41,7 +41,7 @@ generate_enums! { Hash: 12 // TODO: add ReadDir{First,Next}, not loading data, if needed for efficiency ReadDirFilesFirst: 13 - ReadDirFilesNth: 31 + ReadDirFilesNth: 63 ReadDirFilesNext: 14 ReadFile: 15 Metadata: 26 @@ -64,7 +64,7 @@ generate_enums! { // // CreateDir, <-- implied by WriteFile ReadDirFirst: 31 // <-- gets Option to restrict to just dir/file DirEntries, - ReadDirNth: 31 + ReadDirNth: 64 ReadDirNext: 32 // <-- gets Option to restrict to just dir/file DirEntries, // // returns simplified Metadata // // ReadDirFilesFirst: 23 // <-- returns contents @@ -442,7 +442,7 @@ pub mod reply { - entry: Option ReadDirNth: - - data: Option + - entry: Option ReadDirNext: - entry: Option diff --git a/src/api/macros.rs b/src/api/macros.rs index 9a486a72e30..50e30e0c922 100644 --- a/src/api/macros.rs +++ b/src/api/macros.rs @@ -2,17 +2,19 @@ macro_rules! generate_enums { ($($(#[$attr:meta])? $which:ident: $index:literal)*) => { #[derive(Clone, Eq, PartialEq, Debug)] + #[repr(u8)] #[allow(clippy::large_enum_variant)] #[non_exhaustive] pub enum Request { - DummyRequest, // for testing + DummyRequest = 0, // for testing $( $(#[$attr])? - $which(request::$which), + $which(request::$which) = $index, )* } #[derive(Clone, Eq, PartialEq, Debug)] + #[repr(u8)] #[allow(clippy::large_enum_variant)] #[non_exhaustive] pub enum Reply { diff --git a/src/client.rs b/src/client.rs index e73c32b84c4..9e8370753bd 100644 --- a/src/client.rs +++ b/src/client.rs @@ -569,6 +569,19 @@ pub trait FilesystemClient: PollClient { }) } + fn read_dir_nth( + &mut self, + location: Location, + dir: PathBuf, + start_at: usize, + ) -> ClientResult<'_, reply::ReadDirNth, Self> { + self.request(request::ReadDirNth { + location, + dir, + start_at, + }) + } + fn read_dir_next(&mut self) -> ClientResult<'_, reply::ReadDirNext, Self> { self.request(request::ReadDirNext {}) } @@ -586,6 +599,21 @@ pub trait FilesystemClient: PollClient { }) } + fn read_dir_files_nth( + &mut self, + location: Location, + dir: PathBuf, + start_at: usize, + user_attribute: Option, + ) -> ClientResult<'_, reply::ReadDirFilesNth, Self> { + self.request(request::ReadDirFilesNth { + dir, + location, + start_at, + user_attribute, + }) + } + fn read_dir_files_next(&mut self) -> ClientResult<'_, reply::ReadDirFilesNext, Self> { self.request(request::ReadDirFilesNext {}) } diff --git a/src/service.rs b/src/service.rs index f5a86d073ea..acfa4bed225 100644 --- a/src/service.rs +++ b/src/service.rs @@ -367,7 +367,7 @@ impl ServiceResources

{ } }; - Ok(Reply::ReadDirFirst(reply::ReadDirFirst { entry: maybe_entry } )) + Ok(Reply::ReadDirNth(reply::ReadDirNth { entry: maybe_entry } )) } Request::ReadDirNext(_request) => { @@ -418,7 +418,7 @@ impl ServiceResources

{ None } }; - Ok(Reply::ReadDirFilesFirst(reply::ReadDirFilesFirst { data: maybe_data } )) + Ok(Reply::ReadDirFilesNth(reply::ReadDirFilesNth { data: maybe_data } )) } Request::ReadDirFilesNext(_request) => { diff --git a/src/store/filestore.rs b/src/store/filestore.rs index 83f046420dc..a96d813bfee 100644 --- a/src/store/filestore.rs +++ b/src/store/filestore.rs @@ -7,14 +7,14 @@ use crate::{ }; use littlefs2::path; -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct ReadDirState { real_dir: PathBuf, location: Location, position: DirIterationTell, } -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct ReadDirFilesState { real_dir: PathBuf, position: DirIterationTell, diff --git a/tests/filesystem.rs b/tests/filesystem.rs index 08ca8efe511..d3cadff84b6 100644 --- a/tests/filesystem.rs +++ b/tests/filesystem.rs @@ -55,34 +55,52 @@ fn escape_namespace_root() { } fn iterating(location: Location) { - client::get(|client| { - syscall!(client.write_file( - location, - PathBuf::from("foo"), - Bytes::from_slice(b"foo").unwrap(), - None - )); - syscall!(client.write_file( - location, - PathBuf::from("bar"), - Bytes::from_slice(b"bar").unwrap(), - None - )); - let first_entry = syscall!(client.read_dir_first(location, PathBuf::from(""), None)) - .entry - .unwrap(); - assert_eq!(first_entry.file_name(), "bar"); + for count in [0, 1, 10, 20] { + let files: Vec<_> = (0..count).map(|i| format!("file{i:04}")).collect(); + client::get(|client| { + // Setup filesystem + for file in &files { + syscall!(client.write_file( + location, + PathBuf::from(&**file), + Bytes::from_slice(file.as_bytes()).unwrap(), + None + )); + } + + // Iteration over entries (filenames) + for i in 0..count { + if let Some(f) = files.get(i) { + let entry = syscall!(client.read_dir_nth(location, PathBuf::new(), i)) + .entry + .unwrap(); + assert_eq!(entry.path().as_ref(), f); + } + + for j in i + 1..count { + let entry = syscall!(client.read_dir_next()).entry.unwrap(); + assert_eq!(entry.path().as_ref(), &files[j]); + } + assert!(syscall!(client.read_dir_next()).entry.is_none()); + } - let next_entry = syscall!(client.read_dir_next()).entry.unwrap(); - assert_eq!(next_entry.file_name(), "foo"); + for i in 0..count { + if let Some(f) = files.get(i) { + let data = + syscall!(client.read_dir_files_nth(location, PathBuf::new(), i, None)) + .data + .unwrap(); + assert_eq!(data, f.as_bytes()); + } - let first_data = syscall!(client.read_dir_files_first(location, PathBuf::from(""), None)) - .data - .unwrap(); - assert_eq!(first_data, b"bar"); - let next_data = syscall!(client.read_dir_files_next()).data.unwrap(); - assert_eq!(next_data, b"foo"); - }); + for j in i + 1..count { + let data = syscall!(client.read_dir_files_next()).data.unwrap(); + assert_eq!(data, files[j].as_bytes()); + } + assert!(syscall!(client.read_dir_files_next()).data.is_none()); + } + }); + } } #[test] From 0ecbb7bd4a6ffbc162051dc91963f9cb26905b72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sosth=C3=A8ne=20Gu=C3=A9don?= Date: Thu, 6 Apr 2023 16:18:10 +0200 Subject: [PATCH 4/5] Fix clippy warnings --- tests/filesystem.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/filesystem.rs b/tests/filesystem.rs index d3cadff84b6..b489f694abc 100644 --- a/tests/filesystem.rs +++ b/tests/filesystem.rs @@ -77,9 +77,9 @@ fn iterating(location: Location) { assert_eq!(entry.path().as_ref(), f); } - for j in i + 1..count { + for file in &files[i + 1..count] { let entry = syscall!(client.read_dir_next()).entry.unwrap(); - assert_eq!(entry.path().as_ref(), &files[j]); + assert_eq!(entry.path().as_ref(), file); } assert!(syscall!(client.read_dir_next()).entry.is_none()); } @@ -93,9 +93,9 @@ fn iterating(location: Location) { assert_eq!(data, f.as_bytes()); } - for j in i + 1..count { + for file in &files[i + 1..count] { let data = syscall!(client.read_dir_files_next()).data.unwrap(); - assert_eq!(data, files[j].as_bytes()); + assert_eq!(data, file.as_bytes()); } assert!(syscall!(client.read_dir_files_next()).data.is_none()); } From f48ccefab20ca02b1539ed4c861a784fd38be890 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sosth=C3=A8ne=20Gu=C3=A9don?= Date: Fri, 9 Jun 2023 17:31:13 +0200 Subject: [PATCH 5/5] Fix warnings --- src/store/certstore.rs | 5 +---- src/store/counterstore.rs | 5 +---- src/store/keystore.rs | 5 +---- 3 files changed, 3 insertions(+), 12 deletions(-) diff --git a/src/store/certstore.rs b/src/store/certstore.rs index 63b0ba187ac..54352b68d0f 100644 --- a/src/store/certstore.rs +++ b/src/store/certstore.rs @@ -1,7 +1,4 @@ -use littlefs2::{ - path, - path::{Path, PathBuf}, -}; +use littlefs2::{path, path::PathBuf}; use rand_chacha::ChaCha8Rng; use crate::{ diff --git a/src/store/counterstore.rs b/src/store/counterstore.rs index da3d5bdc783..1b14c82d35f 100644 --- a/src/store/counterstore.rs +++ b/src/store/counterstore.rs @@ -1,7 +1,4 @@ -use littlefs2::{ - path, - path::{Path, PathBuf}, -}; +use littlefs2::{path, path::PathBuf}; use rand_chacha::ChaCha8Rng; use crate::{ diff --git a/src/store/keystore.rs b/src/store/keystore.rs index 4241ec5337a..000f83edddf 100644 --- a/src/store/keystore.rs +++ b/src/store/keystore.rs @@ -1,7 +1,4 @@ -use littlefs2::{ - path, - path::{Path, PathBuf}, -}; +use littlefs2::{path, path::PathBuf}; use rand_chacha::ChaCha8Rng; use crate::{