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

Advice for locating a LFS filesystem in flash #743

Open
btsimonh opened this issue Oct 31, 2022 · 3 comments
Open

Advice for locating a LFS filesystem in flash #743

btsimonh opened this issue Oct 31, 2022 · 3 comments

Comments

@btsimonh
Copy link

We've got an application where we share OTA and LFS flash areas.
I've just implemented a firmware command which allows the size of the LFS to be set, only applied on re-format.

(I've fixed the END of LFS to the end of the OTA area, and so allow LFS to be configured to occupy currently unused OTA flash and not get destroyed if the OTA file is smaller than the remaining flash area).

However, I'd like to be able to locate an existing LFS by walking DOWN the blocks until I find the first LFS block.

It this possible? in a quick scan, I can't find reference to any kind of simple magic number for the FIRST block.
And it looks like lfs_rawmount will search forward for superblocks.... so If I handed it a block from the middle of the FS which happenned to be correct, it could go badly wrong?

Every idea welcome :)

@geky
Copy link
Member

geky commented Nov 4, 2022

Hi @btsimonh, thanks for opening an issue. This is an interesting puzzle.

It's a bit hidden in the documentation, but there is actually a magic number that helps identify the superblocks. Every superblock constaints the 8-byte string "littlefs" at offset 8 bytes.

(Pardon the bad paint job):
image

The actual problem is that littlefs can't guarantee there will always be a superblock at block 0. Mutating flash requires an erase, and littlefs does store/mutate files in block 0, so block 0 can end up erased/partially written after a power-loss. This is especially problematic for #349.

One option would be to add a partition record in a known/discoverable block. MBR is a common/simple standard for this. Though this would cost an extra block.

This may be worth adding a new feature to differentiate the two superblocks. It wouldn't be too difficult to enforce the lowest bit of the revision count to be 0=first superblock and 1=second superblock.

@btsimonh
Copy link
Author

btsimonh commented Nov 5, 2022

thanks for the detail;
it's as I thought, more complicated than worthwhile;
keeping in mind that I'm keeping the LAST block at the same place for different sizes of LFS:
e.g. if someone had a 16k FS, and expanded to a 32fs, but wrote nothing big, the new FS would not have erased the blocks from the 16kfs, and so they would still be found in a backward search :(.
I actually had this exact scenario by expanding from 16k to 32k, then setting back to 16k - the 16k FS was still valid, and LFS mounted on the device with the original files in the 16k fs....

So I think the best solution for me is detailed documentation of the dangers :)

@geky
Copy link
Member

geky commented Nov 7, 2022

Ah I didn't catch the scanning from the end, that is a bit difficult. And if you care about malicious actors could be intercepted with a deceptive file.

Hmmm, one creative/nonstandard solution would be to map block numbers to negative block numbers, so block 0 =>block N-1, block 1 => block N-2, block n => block N-n-1. This could be done transparently in the block device layer and would result in the superblocks always residing in the last blocks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants