top | item 38596335

Littlefs – a little fail-safe filesystem designed for microcontrollers

121 points| pabs3 | 2 years ago |github.com | reply

21 comments

order
[+] hdgr|2 years ago|reply
We use littlefs in Flipper Zero's firmware[1] for storage in leftover flash space after the main firmware image. Flipper implements a virtual FS, where both external SD card and internal storage have own mount points. SD card is used for storing apps and user-created data, and internal littlefs contains persistent data like BLE pairing, system services' configs and such.

LFS has neat features like wear leveling and optimizations for storing tiny files directly in their parent directory's data structures[2].

We never had any issues with littlefs - however, it cannot be easily resized when amount of available leftover space changes with firmware updates. So on installing an update, it gets fully backed up to SD card, reformatted and later restored.

[1] - https://github.com/flipperdevices/flipperzero-firmware/blob/...

[2] - https://github.com/littlefs-project/littlefs/blob/master/DES...

[+] aappleby|2 years ago|reply
A caveat for anyone wanting to use this - while the library does work and the test suite seems thorough, the implementation does some _very_ sketchy things like forcibly casting pointers to unrelated types so they can be shoved through some multiply-recursive functions and then cast back to the correct type later.

A team I was on a while back ended up abandoning LittleFS as we couldn't fully trust the C implementation and my two separate attempts to port it to Rust both proved futile (_everything_ had to be unsafe).

[+] zoomablemind|2 years ago|reply
> ...the implementation does some _very_ sketchy things like forcibly casting pointers to unrelated types so they can be shoved through some multiply-recursive functions and then cast back to the correct type later.

I did not look into the code, however such casts can be a reasonable way to implement polymorphism in C.

Of course, having some common type field would be more robust, instead of blindly casting whatever pointer comes at input.

For example, such type could be defined as first field in the 'base' structure. Thus the cast into, say, `int` should yield a valid/expected type value, which would be checked in the called functions before casting into the expected type.

[+] tom_|2 years ago|reply
Pointers correctly round-trip through unrelated pointer types, provided the alignment for both types is compatible.

At least one bit does look a bit questionable: lfs_mlist is treated as the common initial sequence of lfs_dir and lfs_file, even though it isn't, and common initial sequences only apply to union fields anyway. Example cast of struct dir * to struct lfs_mlist * (probably valid of itself, assuming the alignment is compatible): https://github.com/littlefs-project/littlefs/blob/c733d9ec57... then use struct dir as if it were actually a struct lfs_mlist: https://github.com/littlefs-project/littlefs/blob/c733d9ec57...

(There's other occurrences of the same kind of thing.)

Strictly speaking, I think this might be unfixable without a bunch of work, but so much stuff does this kind of operation that any compiler that doesn't do what you expect will have been fixed by now. (Assuming you're not one of those people who is going to pop up and tell us with a straight face that what we should expect is for the compiler to do absolutely anything - except, perhaps, for having it generate correct code, which would be defective behaviour that should be eliminated.) Maybe improve the odds by using lfs_mlist as the common initial sequence of both structs, and fingers crossed that the compiler considers the union rules to apply to this case too. Or compile with -fno-strict-aliasing.

[+] SV_BubbleTime|2 years ago|reply
I can tell you take offense to the questionable casting… but did you discover anywhere it made mistakes and failed - or you just didn’t like it?
[+] hinkley|2 years ago|reply
What prevents you from taking the underlying data structures and reimplementing the API?
[+] thenewwazoo|2 years ago|reply
What do you recommend instead?
[+] quadhome|2 years ago|reply
We used littlefs on an embedded project. Everything worked as advertised! Solid.

We kept up with all their releases until their latest API changes forced us to fork to keep our anti-glitching mitigations.

[+] jpcfl|2 years ago|reply
Very cool. FYI, I had to remove some compiler flags and change the 'section' attributes to get the tests building with Clang, but it seems to be working on my Mac.

I was looking for a benchmark that would give me an idea of the RAM/ROM footprint for the library, but I don't see one.