Skip to content

Commit

Permalink
Update littlefs2
Browse files Browse the repository at this point in the history
  • Loading branch information
robin-nitrokey committed Aug 13, 2024
1 parent 7b065dd commit a961479
Show file tree
Hide file tree
Showing 15 changed files with 95 additions and 97 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -147,4 +147,4 @@ features = ["serde-extensions", "virt"]
rustdoc-args = ["--cfg", "docsrs"]

[patch.crates-io]
littlefs2 = { git = "https://github.com/sosthene-nitrokey/littlefs2.git", rev = "2b45a7559ff44260c6dd693e4cb61f54ae5efc53" }
littlefs2 = { git = "https://github.com/trussed-dev/littlefs2.git", branch = "core" }
4 changes: 2 additions & 2 deletions src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -795,9 +795,9 @@ impl ClientBuilder {
///
/// Per default, the client does not support backends and always uses the Trussed core
/// implementation to execute requests.
pub fn new(id: impl Into<PathBuf>) -> Self {
pub fn new(id: PathBuf) -> Self {
Self {
id: id.into(),
id,
backends: &[],
interrupt: None,
}
Expand Down
10 changes: 5 additions & 5 deletions src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ impl<P: Platform> ServiceResources<P> {
}

pub fn trussed_filestore(&mut self) -> ClientFilestore<P::S> {
ClientFilestore::new(PathBuf::from("trussed"), self.platform.store())
ClientFilestore::new(path!("trussed").into(), self.platform.store())
}

pub fn keystore(&mut self, client_id: PathBuf) -> Result<ClientKeystore<P::S>> {
Expand Down Expand Up @@ -182,7 +182,7 @@ impl<P: Platform> ServiceResources<P> {
#[cfg(feature = "crypto-client-attest")]
Request::Attest(request) => {
let mut attn_keystore: ClientKeystore<P::S> = ClientKeystore::new(
PathBuf::from("attn"),
path!("attn").into(),
self.rng().map_err(|_| Error::EntropyMalfunction)?,
full_store,
);
Expand Down Expand Up @@ -854,7 +854,7 @@ impl<P: Platform> Service<P> {
/// interchange pairs.
pub fn try_new_client<S: Syscall>(
&mut self,
client_id: &str,
client_id: PathBuf,
syscall: S,
interrupt: Option<&'static InterruptFlag>,
) -> Result<ClientImplementation<S>, Error> {
Expand All @@ -869,7 +869,7 @@ impl<P: Platform> Service<P> {
/// single-app runners.
pub fn try_as_new_client(
&mut self,
client_id: &str,
client_id: PathBuf,
interrupt: Option<&'static InterruptFlag>,
) -> Result<ClientImplementation<&mut Self>, Error> {
ClientBuilder::new(client_id)
Expand All @@ -882,7 +882,7 @@ impl<P: Platform> Service<P> {
/// Service and is therefore `'static`
pub fn try_into_new_client(
mut self,
client_id: &str,
client_id: PathBuf,
interrupt: Option<&'static InterruptFlag>,
) -> Result<ClientImplementation<Self>, Error> {
ClientBuilder::new(client_id)
Expand Down
34 changes: 11 additions & 23 deletions src/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@
use littlefs2::{driver::Storage, fs::Filesystem};

use crate::error::Error;
use crate::types::{Bytes, Location, PathBuf};
use crate::types::{Bytes, Location};
#[allow(unused_imports)]
use littlefs2::{
fs::{DirEntry, Metadata},
Expand Down Expand Up @@ -492,24 +492,10 @@ macro_rules! store {
};
}

// TODO: replace this with "fs.create_dir_all(path.parent())"
pub fn create_directories(fs: &dyn DynFilesystem, path: &Path) -> Result<(), Error> {
let path_bytes = path.as_ref().as_bytes();

for i in 0..path_bytes.len() {
if path_bytes[i] == b'/' {
let dir_bytes = &path_bytes[..i];
let dir = PathBuf::from(dir_bytes);
// let dir_str = core::str::from_utf8(dir).unwrap();
// fs.create_dir(dir).map_err(|_| Error::FilesystemWriteFailure)?;
match fs.create_dir(&dir) {
Err(littlefs2::io::Error::EntryAlreadyExisted) => {}
Ok(()) => {}
error => {
panic!("{:?}", &error);
}
}
}
if let Some(parent) = path.parent() {
fs.create_dir_all(&parent)
.map_err(|_| Error::FilesystemWriteFailure)?;
}
Ok(())
}
Expand Down Expand Up @@ -579,11 +565,13 @@ pub fn metadata(
path: &Path,
) -> Result<Option<Metadata>, Error> {
debug_now!("checking existence of {}", &path);
match store.fs(location).metadata(path) {
Ok(metadata) => Ok(Some(metadata)),
Err(littlefs2::io::Error::NoSuchEntry) => Ok(None),
Err(_) => Err(Error::FilesystemReadFailure),
}
store.fs(location).metadata(path).map(Some).or_else(|err| {
if err == littlefs2::io::Error::NO_SUCH_ENTRY {
Ok(None)
} else {
Err(Error::FilesystemReadFailure)
}
})
}

#[inline(never)]
Expand Down
2 changes: 1 addition & 1 deletion src/store/certstore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ impl<S: Store> ClientCertstore<S> {
let mut path = PathBuf::new();
path.push(&self.client_id);
path.push(path!("x5c"));
path.push(&PathBuf::from(id.hex().as_slice()));
path.push(&id.hex_path());
path
}

Expand Down
2 changes: 1 addition & 1 deletion src/store/counterstore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ impl<S: Store> ClientCounterstore<S> {
let mut path = PathBuf::new();
path.push(&self.client_id);
path.push(path!("ctr"));
path.push(&PathBuf::from(id.hex().as_slice()));
path.push(&id.hex_path());
path
}

Expand Down
13 changes: 7 additions & 6 deletions src/store/filestore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@ impl<S: Store> ClientFilestore<S> {
// oh oh oh
.unwrap();
let dat_offset = "/dat/".len();
PathBuf::from(&bytes[end_of_namespace + 1 + offset + dat_offset..])
let bytes = &bytes[end_of_namespace + 1 + offset + dat_offset..];
PathBuf::try_from(bytes).unwrap()
}
}

Expand Down Expand Up @@ -204,7 +205,7 @@ impl<S: Store> ClientFilestore<S> {
// `read_dir_and_then` wants to see Results (although we naturally have an Option
// at this point)
})
.ok_or(littlefs2::io::Error::Io)
.ok_or(littlefs2::io::Error::IO)
})
.ok())
}
Expand Down Expand Up @@ -241,7 +242,7 @@ impl<S: Store> ClientFilestore<S> {

(entry, read_dir_state)
})
.ok_or(littlefs2::io::Error::Io)
.ok_or(littlefs2::io::Error::IO)
})
.ok())
}
Expand Down Expand Up @@ -295,7 +296,7 @@ impl<S: Store> ClientFilestore<S> {
// `read_dir_and_then` wants to see Results (although we naturally have an Option
// at this point)
})
.ok_or(littlefs2::io::Error::Io)
.ok_or(littlefs2::io::Error::IO)
})
.ok()
.map(|(i, data)| {
Expand Down Expand Up @@ -355,7 +356,7 @@ impl<S: Store> ClientFilestore<S> {
(i, data)
})
// convert Option into Result, again because `read_dir_and_then` expects this
.ok_or(littlefs2::io::Error::Io)
.ok_or(littlefs2::io::Error::IO)
})
.ok()
.map(|(i, data)| {
Expand Down Expand Up @@ -503,7 +504,7 @@ impl<S: Store> Filestore for ClientFilestore<S> {
}
})
.next()
.ok_or(littlefs2::io::Error::Io)
.ok_or(littlefs2::io::Error::IO)
})
.ok()
}
Expand Down
2 changes: 1 addition & 1 deletion src/store/keystore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ impl<S: Store> ClientKeystore<S> {

pub fn key_path(&self, secrecy: key::Secrecy, id: &KeyId) -> PathBuf {
let mut path = self.key_directory(secrecy);
path.push(&PathBuf::from(id.hex().as_slice()));
path.push(&id.hex_path());
path
}
}
Expand Down
28 changes: 13 additions & 15 deletions src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@ use littlefs2::const_ram_storage;
use littlefs2::driver::Storage as LfsStorage;
use littlefs2::fs::{Allocation, Filesystem};
use littlefs2::io::Result as LfsResult;
use littlefs2::path;
use rand_core::{CryptoRng, RngCore};

#[cfg(any(feature = "p256", feature = "p384", feature = "p521",))]
use crate::types::{Mechanism, SignatureSerialization, StorageAttributes};

use crate::client::{CryptoClient as _, FilesystemClient as _};
use crate::types::{consent, reboot, ui, Bytes, Location, PathBuf};
use crate::types::{consent, reboot, ui, Bytes, Location};
use crate::{api, block, platform, store, Error};

pub struct MockRng(ChaCha20);
Expand Down Expand Up @@ -172,7 +173,7 @@ macro_rules! setup {
let (test_trussed_requester, test_trussed_responder) = crate::pipe::TRUSSED_INTERCHANGE
.claim()
.expect("could not setup TEST TrussedInterchange");
let test_client_id = "TEST";
let test_client_id = path!("TEST");

assert!(trussed
.add_endpoint(test_trussed_responder, test_client_id, &[], None)
Expand Down Expand Up @@ -875,33 +876,30 @@ fn rng() {
fn filesystem() {
setup!(client);

let path = path!("test_file");

assert!(block!(client
.entry_metadata(Location::Internal, PathBuf::from("test_file"))
.entry_metadata(Location::Internal, path.into())
.expect("no client error"))
.expect("no errors")
.metadata
.is_none(),);

let data = Bytes::from_slice(&[0; 20]).unwrap();
block!(client
.write_file(
Location::Internal,
PathBuf::from("test_file"),
data.clone(),
None,
)
.write_file(Location::Internal, path.into(), data.clone(), None,)
.expect("no client error"))
.expect("no errors");

let recv_data = block!(client
.read_file(Location::Internal, PathBuf::from("test_file"))
.read_file(Location::Internal, path.into())
.expect("no client error"))
.expect("no errors")
.data;
assert_eq!(data, recv_data);

let metadata = block!(client
.entry_metadata(Location::Internal, PathBuf::from("test_file"))
.entry_metadata(Location::Internal, path.into())
.expect("no client error"))
.expect("no errors")
.metadata
Expand All @@ -910,23 +908,23 @@ fn filesystem() {

// This returns an error because the name doesn't exist
block!(client
.remove_file(Location::Internal, PathBuf::from("bad_name"))
.remove_file(Location::Internal, path!("bad_name").into())
.expect("no client error"))
.ok();
let metadata = block!(client
.entry_metadata(Location::Internal, PathBuf::from("test_file"))
.entry_metadata(Location::Internal, path.into())
.expect("no client error"))
.expect("no errors")
.metadata
.unwrap();
assert!(metadata.is_file());

block!(client
.remove_file(Location::Internal, PathBuf::from("test_file"))
.remove_file(Location::Internal, path.into())
.expect("no client error"))
.expect("no errors");
assert!(block!(client
.entry_metadata(Location::Internal, PathBuf::from("test_file"))
.entry_metadata(Location::Internal, path.into())
.expect("no client error"))
.expect("no errors")
.metadata
Expand Down
11 changes: 8 additions & 3 deletions src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,11 @@ impl Id {
buffer
}

pub fn hex_path(&self) -> PathBuf {
// the hex representation is always ascii-only and has a valid length, so this cannot panic
PathBuf::try_from(self.hex().as_slice()).unwrap()
}

/// skips leading zeros
pub fn hex_clean(&self) -> String<32> {
const HEX_CHARS: &[u8] = b"0123456789abcdef";
Expand Down Expand Up @@ -326,9 +331,9 @@ impl From<PathBuf> for CoreContext {
}
}

impl From<&str> for CoreContext {
fn from(s: &str) -> Self {
Self::new(s.into())
impl From<&Path> for CoreContext {
fn from(path: &Path) -> Self {
Self::new(path.into())
}
}

Expand Down
15 changes: 10 additions & 5 deletions src/virt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,9 @@ impl<S: Syscall> Syscall for Arc<Mutex<S>> {
impl<S: StoreProvider> Platform<S> {
pub fn run_client<R>(self, client_id: &str, test: impl FnOnce(Client<S>) -> R) -> R {
let service = Service::new(self);
let client = service.try_into_new_client(client_id, None).unwrap();
let client = service
.try_into_new_client(client_id.try_into().unwrap(), None)
.unwrap();
test(client)
}

Expand All @@ -143,7 +145,7 @@ impl<S: StoreProvider> Platform<S> {
test: impl FnOnce(Client<S, D>) -> R,
) -> R {
let mut service = Service::with_dispatch(self, dispatch);
let client = ClientBuilder::new(client_id)
let client = ClientBuilder::new(client_id.try_into().unwrap())
.backends(backends)
.prepare(&mut service)
.unwrap()
Expand All @@ -157,8 +159,11 @@ impl<S: StoreProvider> Platform<S> {
test: impl FnOnce([MultiClient<S>; N]) -> R,
) -> R {
let mut service = Service::new(self);
let prepared_clients =
client_ids.map(|id| ClientBuilder::new(id).prepare(&mut service).unwrap());
let prepared_clients = client_ids.map(|id| {
ClientBuilder::new(id.try_into().unwrap())
.prepare(&mut service)
.unwrap()
});
let service = Arc::new(Mutex::new(service));
test(prepared_clients.map(|builder| builder.build(service.clone())))
}
Expand All @@ -172,7 +177,7 @@ impl<S: StoreProvider> Platform<S> {
) -> R {
let mut service = Service::with_dispatch(self, dispatch);
let prepared_clients = client_ids.map(|(id, backends)| {
ClientBuilder::new(id)
ClientBuilder::new(id.try_into().unwrap())
.backends(backends)
.prepare(&mut service)
.unwrap()
Expand Down
4 changes: 2 additions & 2 deletions src/virt/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ impl Storage for FilesystemStorage {
fn write(&mut self, offset: usize, data: &[u8]) -> LfsResult<usize> {
debug!("write: offset: {}, len: {}", offset, data.len());
if offset + data.len() > STORAGE_SIZE {
return Err(littlefs2::io::Error::NoSpace);
return Err(littlefs2::io::Error::NO_SPACE);
}
let mut file = OpenOptions::new().write(true).open(&self.0).unwrap();
file.seek(SeekFrom::Start(offset as _)).unwrap();
Expand All @@ -79,7 +79,7 @@ impl Storage for FilesystemStorage {
fn erase(&mut self, offset: usize, len: usize) -> LfsResult<usize> {
debug!("erase: offset: {}, len: {}", offset, len);
if offset + len > STORAGE_SIZE {
return Err(littlefs2::io::Error::NoSpace);
return Err(littlefs2::io::Error::NO_SPACE);
}
let mut file = OpenOptions::new().write(true).open(&self.0).unwrap();
file.seek(SeekFrom::Start(offset as _)).unwrap();
Expand Down
Loading

0 comments on commit a961479

Please sign in to comment.