Skip to content

v2.10

Compare
Choose a tag to compare
@geky-bot geky-bot released this 11 Dec 23:59
630a0d8

This holiday themed release brings in some minor, but highly requested, features.

Potentially breaking changes:

  • Path parsing has been reworked internally to better align with POSIX/user expectations in a number of corner cases. This changes behavior of paths with trailing slashes, navigating above root, and empty paths.

    See path changes below for a full list of what's changed.

What's new?

  • Path parsing has been reworked internally to better align with POSIX/user expectations in a number of corner cases (#1046)

    See path changes below for more details.

  • Thanks to @yamt, LFS_DEFINES now provides an easier alternative to LFS_CONFIG for partial util overrides (#1004)

    This is useful for when you want to override some parts of lfs_utils.h, but keep most of the existing definitions:

    // in my_utils.h
    #include <stddef.h>
    extern void *my_malloc(size_t sz);
    #define LFS_MALLOC(sz) my_malloc(sz)
    # in compile flags
    -DLFS_DEFINES=my_utils.h
  • @wdfk-prog found some nice code savings by deduplicating lfs_tortoise_detectcycles (#1013)

  • Thanks to @wangdongustc, littlefs now asserts if block-device callbacks are NULL (#1052)

  • Added links to ramcrc32bd and ramrsbd (#1038)

    These are two new example block devices that implement error-correction compatible with littlefs (or any filesystem really).

    littlefs currently does not provide error-correction or error-detection. These are intended to be a good starting point if this is a requirement for your system.

  • Fixed metadata compaction bug that may cause early LFS_ERR_NOSPC when using metadata_max (#1031)

  • Fixed undefined signed overflow in lfs_file_seek found by @m-kostrzewa and @lucic71 (#1027)

  • Fixed some LFS_TRACE format specifiers found by @stefano-zanotti (#997)

  • Thanks to @yamt, fixed an annoying GitHub Actions breakage (#1026)

Path changes

  • lfs_mkdir now accepts trailing slashes:

    before: lfs_mkdir("a/") => LFS_ERR_NOENT
    after:  lfs_mkdir("a/") => 0
  • lfs_stat, lfs_getattr, etc, now reject trailing slashes if the file is not a directory:

    before: lfs_stat("reg_a/") => 0
    after:  lfs_stat("reg_a/") => LFS_ERR_NOTDIR

    Note trailing slashes are accepted if the file is a directory:

    before: lfs_stat("dir_a/") => 0
    after:  lfs_stat("dir_a/") => 0
  • lfs_file_open now returns LFS_ERR_NOTDIR if the path contains trailing slashes and the file is not a directory, or LFS_O_CREAT is specified and the file does not exist:

    before: lfs_file_open("reg_a/") => LFS_ERR_NOENT
    after:  lfs_file_open("reg_a/") => LFS_ERR_NOTDIR

    Note trailing slashes return LFS_ERR_ISDIR if the file is a directory:

    before: lfs_file_open("dir_a/") => LFS_ERR_ISDIR
    after:  lfs_file_open("dir_a/") => LFS_ERR_ISDIR

    Note LFS_ERR_NOENT takes priority if LFS_O_CREAT is not specified:

    before: lfs_file_open("missing_a/") => LFS_ERR_NOENT
    after:  lfs_file_open("missing_a/") => LFS_ERR_NOENT
  • Attempting to navigate above the root directory now returns LFS_ERR_INVAL:

    before: lfs_stat("/../a") => 0
    after:  lfs_stat("/../a") => LFS_ERR_INVAL

    This actually moves away from the behavior of other filesystems, but towards, in my opinion, more reasonable behavior. It should also be more consistent with future theoretical openat-like APIs.

  • The empty path ("") no longer aliases the root directory, now returns LFS_ERR_INVAL:

    before: lfs_stat("") => 0
    after:  lfs_stat("") => LFS_ERR_INVAL

POSIX deviations

While this gets us closer to POSIX, there are still some subtle differences in behaviors. These shouldn't affect most users, but are worth documenting. Most of these are due to 1. littlefs not actually creating . and .. entries on disk and 2. not using recursion during path resolution.

  • Root modifications return EINVAL instead of EBUSY:

    littlefs: remove("/") => EINVAL
    POSIX:    remove("/") => EBUSY

    Reason: This would be the only use of EBUSY in the system.

  • We accept modifications of directories with trailing dots:

    littlefs: remove("a/.") => 0
    POSIX:    remove("a/.") => EBUSY

    Reason: Not worth implementing.

  • We do not check for existence of directories followed by dotdots:

    littlefs: stat("a/missing/..") => 0
    POSIX:    stat("a/missing/..") => ENOENT

    Reason: Difficult to implement non-recursively.

  • We accept modifications of directories with trailing dotdots:

    littlefs: rename("a/b/..", "c") => 0
    POSIX:    rename("a/b/..", "c") => EBUSY

    Reason: Not worth implementing.

Changes

Code Stack Structs Coverage
Default 17128 B (+0.4%) 1440 B (+0.0%) 812 B (+0.0%) Lines 2399/2571 lines (+0.3%)
Readonly 6250 B (+0.9%) 448 B (+0.0%) 812 B (+0.0%) Branches 1283/1616 branches (+0.8%)
Threadsafe 17976 B (+0.3%) 1440 B (+0.0%) 820 B (+0.0%) Benchmarks
Multiversion 17200 B (+0.4%) 1440 B (+0.0%) 816 B (+0.0%) Readed 29369693876 B (+0.0%)
Migrate 18816 B (+0.3%) 1736 B (-0.5%) 816 B (+0.0%) Proged 1482874766 B (+0.0%)
Error-asserts 17892 B (+0.8%) 1432 B (+0.0%) 812 B (+0.0%) Erased 1568888832 B (+0.0%)

3d03864 Bumped minor version to v2.10
dae656a Fix prettyasserts.py for pointer asserts
469c863 Assert on NULL IO function
215613e gha: Fixed x86-only statuses
999ef66 paths: Changed CREAT with a trailing slash to return NOTDIR
b735c8f paths: Added tests over NOENT + trailing slash/dot
3094705 paths: Extended tests to cover open with CREAT/EXCL
80ca1ea paths: Reject empty paths
815f0d8 paths: Fixed dots followed by dotdots
dc92dec paths: Reject dotdots above root
a603507 paths: Fixed/doc trailing slash/dot POSIX incompatibilities
232e736 paths: Added trailing slashes and dots tests
0de0389 paths: Reworked test_paths to cover more corner cases
1407db9 Added links to ramcrc32bd and ramrsbd
ea431bd Added some checks that metadata_max makes sense
2d62d2f Fixed metadata_max==prog_size commit->end calculation
1f82c0f Added some metadata_max testing
a2c2e49 Write the detect cycles function as a function to optimize code
abaec45 Fixed seek undefined behavior on signed integer overflow
f1c430e Added some tests around seek integer overflow/underflow
4a845be Rename LFS_USER_DEFINES to LFS_DEFINES
e1636d0 Add an alternative way to override LFS_MALLOC etc
798073c gha: Dropped minor/patch version pinning of actions
7db9e16 gha: Switched to standard da for cross-workflow downloads
2c4b262 gha: Merge artifacts on download
72a4b57 gha: Make the artifact names unique
6e72698 gha: Update github actions to the latest versions
ac20758 Fixed some more LFS_TRACE format specifiers

Sponsors

A special thanks to littlefs's sponsors: @fusedFET, @kmetabg, @Eclo