Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove store! macro #202

Merged
merged 1 commit into from
Mar 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Removed the `Syscall` implementations for `Service` and the `Syscall::try_as_new_client` and `Syscall::try_new_client` methods.
- Removed `TrussedInterchange` and `TRUSSED_INTERCHANGE` from `pipe`.
- Removed the `clients-?` features.
- Removed the `store!` macro. Embedded runners should provide their own implementation. Software runners can use `virt::StoreConfig` to create a `virt::Store`.

[#64]: https://github.com/trussed-dev/trussed/issues/64
[#65]: https://github.com/trussed-dev/trussed/issues/65
Expand Down
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ delog = "0.1.0"
cbor-smol = { version = "0.5", features = ["heapless-bytes-v0-3"] }
heapless-bytes.workspace = true
interchange = "0.3.0"
littlefs2 = "0.6.1"
littlefs2 = { version = "0.6.1", optional = true }
littlefs2-core = { workspace = true, features = ["heapless-bytes03"] }
p256-cortex-m4 = { version = "0.1.0-alpha.6", features = ["prehash", "sec1-signatures"] }
salty = { version = "0.3.0", features = ["cose"] }
Expand All @@ -77,6 +77,7 @@ entropy = "0.4.0"
once_cell = "1.13.0"
serde_test = "1"
trussed-derive = { path = "derive" }
littlefs2 = "0.6"
# Somehow, this is causing a regression.
# rand_core = { version = "0.5", features = ["getrandom"] }

Expand Down
341 changes: 3 additions & 338 deletions src/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,17 +72,11 @@
//! - Alternative: subdirectory <==> RP hash, everything else in flat files
//! - In any case need to "list dirs excluding . and .." or similar

use littlefs2::path;

use crate::error::Error;
use crate::types::{Bytes, Location};
#[allow(unused_imports)]
use littlefs2::{
fs::{DirEntry, Metadata},
path::Path,
};
use littlefs2_core::{path, DirEntry, Metadata, Path};

pub use littlefs2::object_safe::{DynFile, DynFilesystem, DynStorage};
pub use littlefs2_core::{DynFile, DynFilesystem};

pub mod certstore;
pub mod counterstore;
Expand Down Expand Up @@ -140,335 +134,6 @@ pub trait Store {
}
}

#[macro_export]
macro_rules! store {
(
$store:ident,
Internal: $Ifs:ty,
External: $Efs:ty,
Volatile: $Vfs:ty
) => {
#[derive(Clone, Copy)]
pub struct $store {
// __: $crate::store::NotSendOrSync,
__: core::marker::PhantomData<*mut ()>,
}

impl $crate::store::Store for $store {
fn ifs(&self) -> &dyn littlefs2::object_safe::DynFilesystem {
unsafe { Self::ifs_ptr().assume_init() }
}
fn efs(&self) -> &dyn littlefs2::object_safe::DynFilesystem {
unsafe { Self::efs_ptr().assume_init() }
}
fn vfs(&self) -> &dyn littlefs2::object_safe::DynFilesystem {
unsafe { Self::vfs_ptr().assume_init() }
}
}

impl $store {
#[allow(dead_code)]
pub fn allocate(
internal_fs: $Ifs,
external_fs: $Efs,
volatile_fs: $Vfs,
) -> (
&'static mut littlefs2::fs::Allocation<$Ifs>,
&'static mut $Ifs,
&'static mut littlefs2::fs::Allocation<$Efs>,
&'static mut $Efs,
&'static mut littlefs2::fs::Allocation<$Vfs>,
&'static mut $Vfs,
) {
use core::ptr::addr_of_mut;
// static mut INTERNAL_STORAGE: $Ifs = i_ctor();//<$Ifs>::new();

static mut INTERNAL_STORAGE: Option<$Ifs> = None;
unsafe {
INTERNAL_STORAGE = Some(internal_fs);
}
static mut INTERNAL_FS_ALLOC: Option<littlefs2::fs::Allocation<$Ifs>> = None;
unsafe {
INTERNAL_FS_ALLOC = Some(littlefs2::fs::Filesystem::allocate());
}

// static mut EXTERNAL_STORAGE: $Efs = <$Efs>::new();
static mut EXTERNAL_STORAGE: Option<$Efs> = None;
unsafe {
EXTERNAL_STORAGE = Some(external_fs);
}
static mut EXTERNAL_FS_ALLOC: Option<littlefs2::fs::Allocation<$Efs>> = None;
unsafe {
EXTERNAL_FS_ALLOC = Some(littlefs2::fs::Filesystem::allocate());
}

// static mut VOLATILE_STORAGE: $Vfs = <$Vfs>::new();
static mut VOLATILE_STORAGE: Option<$Vfs> = None;
unsafe {
VOLATILE_STORAGE = Some(volatile_fs);
}
static mut VOLATILE_FS_ALLOC: Option<littlefs2::fs::Allocation<$Vfs>> = None;
unsafe {
VOLATILE_FS_ALLOC = Some(littlefs2::fs::Filesystem::allocate());
}

(
unsafe { (*addr_of_mut!(INTERNAL_FS_ALLOC)).as_mut().unwrap() },
unsafe { (*addr_of_mut!(INTERNAL_STORAGE)).as_mut().unwrap() },
unsafe { (*addr_of_mut!(EXTERNAL_FS_ALLOC)).as_mut().unwrap() },
unsafe { (*addr_of_mut!(EXTERNAL_STORAGE)).as_mut().unwrap() },
unsafe { (*addr_of_mut!(VOLATILE_FS_ALLOC)).as_mut().unwrap() },
unsafe { (*addr_of_mut!(VOLATILE_STORAGE)).as_mut().unwrap() },
)
}

#[allow(dead_code)]
pub fn init(
internal_fs: $Ifs,
external_fs: $Efs,
volatile_fs: $Vfs,
format: bool,
) -> Self {
let (ifs_alloc, ifs_storage, efs_alloc, efs_storage, vfs_alloc, vfs_storage) =
Self::allocate(internal_fs, external_fs, volatile_fs);
let store = Self::claim().unwrap();
store
.mount(
ifs_alloc,
ifs_storage,
efs_alloc,
efs_storage,
vfs_alloc,
vfs_storage,
format,
)
.unwrap();

store
}

#[allow(dead_code)]
pub fn init_raw(
ifs: &'static littlefs2::fs::Filesystem<$Ifs>,
efs: &'static littlefs2::fs::Filesystem<$Efs>,
vfs: &'static littlefs2::fs::Filesystem<$Vfs>,
) -> Self {
Self::ifs_ptr().write(ifs);
Self::efs_ptr().write(efs);
Self::vfs_ptr().write(vfs);
Self::claim().unwrap()
}

#[allow(dead_code)]
pub fn attach(internal_fs: $Ifs, external_fs: $Efs, volatile_fs: $Vfs) -> Self {
Self::init(internal_fs, external_fs, volatile_fs, false)
}

#[allow(dead_code)]
pub fn format(internal_fs: $Ifs, external_fs: $Efs, volatile_fs: $Vfs) -> Self {
Self::init(internal_fs, external_fs, volatile_fs, true)
}

pub fn claim() -> Option<$store> {
use core::sync::atomic::{AtomicBool, Ordering};
// use $crate::store::NotSendOrSync;

static CLAIMED: AtomicBool = AtomicBool::new(false);

if CLAIMED
.compare_exchange_weak(false, true, Ordering::AcqRel, Ordering::Acquire)
.is_ok()
{
// Some(Self { __: unsafe { $crate::store::NotSendOrSync::new() } })
Some(Self {
__: core::marker::PhantomData,
})
} else {
None
}
}

fn ifs_ptr() -> &'static mut core::mem::MaybeUninit<
&'static dyn littlefs2::object_safe::DynFilesystem,
> {
use core::mem::MaybeUninit;
static mut IFS: MaybeUninit<&'static dyn littlefs2::object_safe::DynFilesystem> =
MaybeUninit::uninit();
unsafe { (&raw mut IFS).as_mut().unwrap() }
}

fn efs_ptr() -> &'static mut core::mem::MaybeUninit<
&'static dyn littlefs2::object_safe::DynFilesystem,
> {
use core::mem::MaybeUninit;
static mut EFS: MaybeUninit<&'static dyn littlefs2::object_safe::DynFilesystem> =
MaybeUninit::uninit();
unsafe { (&raw mut EFS).as_mut().unwrap() }
}

fn vfs_ptr() -> &'static mut core::mem::MaybeUninit<
&'static dyn littlefs2::object_safe::DynFilesystem,
> {
use core::mem::MaybeUninit;
static mut VFS: MaybeUninit<&'static dyn littlefs2::object_safe::DynFilesystem> =
MaybeUninit::uninit();
unsafe { (&raw mut VFS).as_mut().unwrap() }
}

// Ignore lint for compatibility
#[allow(clippy::too_many_arguments)]
pub fn mount(
&self,

ifs_alloc: &'static mut littlefs2::fs::Allocation<$Ifs>,
ifs_storage: &'static mut $Ifs,
efs_alloc: &'static mut littlefs2::fs::Allocation<$Efs>,
efs_storage: &'static mut $Efs,
vfs_alloc: &'static mut littlefs2::fs::Allocation<$Vfs>,
vfs_storage: &'static mut $Vfs,

// statics: (
// &'static mut littlefs2::fs::Allocation<$Ifs>,
// &'static mut $Ifs,
// &'static mut littlefs2::fs::Allocation<$Efs>,
// &'static mut $Efs,
// &'static mut littlefs2::fs::Allocation<$Vfs>,
// &'static mut $Vfs,
// ),
// TODO: flag per backend?
format: bool,
) -> littlefs2::io::Result<()> {
use core::mem::MaybeUninit;
use core::ptr::{addr_of, addr_of_mut};
use littlefs2::fs::{Allocation, Filesystem};

static mut IFS_ALLOC: MaybeUninit<&'static mut Allocation<$Ifs>> =
MaybeUninit::uninit();
static mut IFS_STORAGE: MaybeUninit<&'static mut $Ifs> = MaybeUninit::uninit();
static mut IFS: Option<Filesystem<'static, $Ifs>> = None;

static mut EFS_ALLOC: MaybeUninit<&'static mut Allocation<$Efs>> =
MaybeUninit::uninit();
static mut EFS_STORAGE: MaybeUninit<&'static mut $Efs> = MaybeUninit::uninit();
static mut EFS: Option<Filesystem<'static, $Efs>> = None;

static mut VFS_ALLOC: MaybeUninit<&'static mut Allocation<$Vfs>> =
MaybeUninit::uninit();
static mut VFS_STORAGE: MaybeUninit<&'static mut $Vfs> = MaybeUninit::uninit();
static mut VFS: Option<Filesystem<'static, $Vfs>> = None;

// let (ifs_alloc, ifs_storage, efs_alloc, efs_storage, vfs_alloc, vfs_storage) = statics;

unsafe {
// always need to format RAM
Filesystem::format(vfs_storage).expect("can format");
// this is currently a RAM fs too...
Filesystem::format(efs_storage).expect("can format");

if format {
Filesystem::format(ifs_storage).expect("can format");
}

(*addr_of_mut!(IFS_ALLOC)).as_mut_ptr().write(ifs_alloc);
(*addr_of_mut!(IFS_STORAGE)).as_mut_ptr().write(ifs_storage);
IFS = Some(Filesystem::mount(
&mut *(*addr_of_mut!(IFS_ALLOC)).as_mut_ptr(),
&mut *(*addr_of_mut!(IFS_STORAGE)).as_mut_ptr(),
)?);
Self::ifs_ptr().write(addr_of!(IFS).as_ref().unwrap().as_ref().unwrap());

(*addr_of_mut!(EFS_ALLOC)).as_mut_ptr().write(efs_alloc);
(*addr_of_mut!(EFS_STORAGE)).as_mut_ptr().write(efs_storage);
EFS = Some(Filesystem::mount(
&mut *(*addr_of_mut!(EFS_ALLOC)).as_mut_ptr(),
&mut *(*addr_of_mut!(EFS_STORAGE)).as_mut_ptr(),
)?);
Self::efs_ptr().write(addr_of!(EFS).as_ref().unwrap().as_ref().unwrap());

(*addr_of_mut!(VFS_ALLOC)).as_mut_ptr().write(vfs_alloc);
(*addr_of_mut!(VFS_STORAGE)).as_mut_ptr().write(vfs_storage);
VFS = Some(Filesystem::mount(
&mut *(*addr_of_mut!(VFS_ALLOC)).as_mut_ptr(),
&mut *(*addr_of_mut!(VFS_STORAGE)).as_mut_ptr(),
)?);
Self::vfs_ptr().write(addr_of!(VFS).as_ref().unwrap().as_ref().unwrap());

Ok(())
}
}

#[allow(dead_code)]
pub fn attach_else_format(
internal_fs: $Ifs,
external_fs: $Efs,
volatile_fs: $Vfs,
) -> Self {
// This unfortunately repeates the code of `allocate`.
// It seems Rust's borrowing rules go against this.
use core::ptr::addr_of_mut;
use littlefs2::fs::{Allocation, Filesystem};

static mut INTERNAL_STORAGE: Option<$Ifs> = None;
unsafe {
INTERNAL_STORAGE = Some(internal_fs);
}
static mut INTERNAL_FS_ALLOC: Option<Allocation<$Ifs>> = None;
unsafe {
INTERNAL_FS_ALLOC = Some(Filesystem::allocate());
}

// static mut EXTERNAL_STORAGE: $Efs = <$Efs>::new();
static mut EXTERNAL_STORAGE: Option<$Efs> = None;
unsafe {
EXTERNAL_STORAGE = Some(external_fs);
}
static mut EXTERNAL_FS_ALLOC: Option<Allocation<$Efs>> = None;
unsafe {
EXTERNAL_FS_ALLOC = Some(Filesystem::allocate());
}

// static mut VOLATILE_STORAGE: $Vfs = <$Vfs>::new();
static mut VOLATILE_STORAGE: Option<$Vfs> = None;
unsafe {
VOLATILE_STORAGE = Some(volatile_fs);
}
static mut VOLATILE_FS_ALLOC: Option<Allocation<$Vfs>> = None;
unsafe {
VOLATILE_FS_ALLOC = Some(Filesystem::allocate());
}

let store = Self::claim().unwrap();
if store
.mount(
unsafe { (*addr_of_mut!(INTERNAL_FS_ALLOC)).as_mut().unwrap() },
unsafe { (*addr_of_mut!(INTERNAL_STORAGE)).as_mut().unwrap() },
unsafe { (*addr_of_mut!(EXTERNAL_FS_ALLOC)).as_mut().unwrap() },
unsafe { (*addr_of_mut!(EXTERNAL_STORAGE)).as_mut().unwrap() },
unsafe { (*addr_of_mut!(VOLATILE_FS_ALLOC)).as_mut().unwrap() },
unsafe { (*addr_of_mut!(VOLATILE_STORAGE)).as_mut().unwrap() },
false,
)
.is_err()
{
store
.mount(
unsafe { (*addr_of_mut!(INTERNAL_FS_ALLOC)).as_mut().unwrap() },
unsafe { (*addr_of_mut!(INTERNAL_STORAGE)).as_mut().unwrap() },
unsafe { (*addr_of_mut!(EXTERNAL_FS_ALLOC)).as_mut().unwrap() },
unsafe { (*addr_of_mut!(EXTERNAL_STORAGE)).as_mut().unwrap() },
unsafe { (*addr_of_mut!(VOLATILE_FS_ALLOC)).as_mut().unwrap() },
unsafe { (*addr_of_mut!(VOLATILE_STORAGE)).as_mut().unwrap() },
true,
)
.unwrap();
}

store
}
}
};
}

pub fn create_directories(fs: &dyn DynFilesystem, path: &Path) -> Result<(), Error> {
if let Some(parent) = path.parent() {
fs.create_dir_all(&parent)
Expand Down Expand Up @@ -568,7 +233,7 @@ pub fn metadata(
debug_now!("checking existence of {}", &path);
match store.fs(location).metadata(path) {
Ok(metadata) => Ok(Some(metadata)),
Err(littlefs2::io::Error::NO_SUCH_ENTRY) => Ok(None),
Err(littlefs2_core::Error::NO_SUCH_ENTRY) => Ok(None),
Err(_) => Err(Error::FilesystemReadFailure),
}
}
Expand Down
Loading
Loading