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

Introduce littlefs2-core crate #73

Merged
merged 4 commits into from
Aug 15, 2024
Merged

Introduce littlefs2-core crate #73

merged 4 commits into from
Aug 15, 2024

Conversation

robin-nitrokey
Copy link
Member

This PR introduces a littlefs2-core crate that provides an interface that does not depend on a specific littlefs2 version. The goal is to make applications using littlefs2 easier to maintain as they no longer need to be updated if a littlefs2 implementation detail is changed.

The API of littlefs2 is mostly unaffected by this change as all moved items are re-exported under their old name. Some changes are required to de-couple the moved types from the actual implementation. See the changelog for details.

Contrary to the initial proposal in #55, this does not move the DynStorage trait. From my point of view, it is coupled too tightly to the actual storage implementation that could be subject to change. Also, there is no real benefit of having it in the core crate as applications are not expected to use the storage directly. If necessary, we can always add this in the future.

Before the core crate is released, we should consider removing the dir-entry-path feature (and just always including the path) and putting the heapless dependency behind a feature flag with potential support for other versions. But I’d prefer to discuss that separately.

Fixes: #55

Previously, DynFilesystem used OpenOptions for opening files in a custom
mode.  This has two drawbacks:  OpenOptions are constructed using a
callback leading to a rather complex method signature.  And OpenOption
depends on the Filesystem type, making it impossible to move
DynFilesystem into a separate core crate without also moving Filesystem.

This patch makes the FileOpenFlags struct public, changes its backing
type to i32 to avoid unnecessary conversions and changes the
DynFilesystem trait to accept FileOpenFlags instead of an
OpenOptionsCallback.  The affected methods are renamed from
*with_options* to *with_flags*.
To make it easier to maintain applications using littlefs2, this patch
introduces a littlefs2-core crate with the basic types and traits used
by littlefs2, but without a specific implementation.

Fixes: #55
By refactoring the Attribute struct using const generics, we can get rid
of the (public) generic-array dependency.
To reduce the number of global items and for consistency with constants
like u8::MAX, this patch replaces the size constants ATTRBYTES_MAX,
PATH_MAX and PATH_MAX_PLUS_ONE with associated constants
Attribute::MAX_SIZE, PathBuf::MAX_SIZE and PathBuf::MAX_SIZE_PLUS_ONE.
Comment on lines +39 to +46
pub fn is_dir(&self) -> bool {
*self == FileType::Dir
}

pub fn is_file(&self) -> bool {
*self == FileType::File
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I'd rather use matches! here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting. I just copied over the code, but would probably have used == too. It’s more concise and more intuitive and you don’t have to care about the correct order. Why do you prefer matches!?

Copy link
Contributor

@sosthene-nitrokey sosthene-nitrokey Aug 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't depend on the PartialEq implementation. Since not all enums are PartialEq, I tend to prefer matches! everywhere for these small helper methods, even when PartialEq is derived for consistency. Not an important issue.

Copy link
Contributor

@sosthene-nitrokey sosthene-nitrokey left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

We never used attributes so this didn't appear in the initial discussion but I believe their API should be improved before a release of core (maybe not in this PR).

Comment on lines +91 to +96
pub struct Attribute {
id: u8,
data: [u8; Attribute::MAX_SIZE as _],
// invariant: size <= data.len()
size: usize,
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have actual uses of attributes?

I don't like the very large owned buffer maybe this shouldn't be in core for now?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is used in Trussed to implement user attributes, but as far as I see, they are only read and never written. But let’s discuss that separately from this PR.

Comment on lines +76 to +78
fn attribute(&self, path: &Path, id: u8) -> Result<Option<Attribute>>;
fn remove_attribute(&self, path: &Path, id: u8) -> Result<()>;
fn set_attribute(&self, path: &Path, attribute: &Attribute) -> Result<()>;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the attribute code could very well be exposed with a API like that:

fn attribute(&self, path: &Path, id: u8, buf: &mut [u8]) -> Result<Option<usize>>;
fn remove_attribute(&self, path: &Path, id: u8) -> Result<()>;
fn set_attribute(&self, id: u8, path: &Path, id: u8, data: &[u8)) -> Result<()>;

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need a low-level object-safe API like you suggested, and a non-object-safe but more user-friendly API. I’ll open a separate PR for that.

@robin-nitrokey robin-nitrokey merged commit 95fd60a into main Aug 15, 2024
8 checks passed
@robin-nitrokey robin-nitrokey deleted the core branch August 15, 2024 06:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Extract core types into separate crate
2 participants