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

Block count defined twice #957

Open
tredlich00 opened this issue Mar 14, 2024 · 1 comment
Open

Block count defined twice #957

tredlich00 opened this issue Mar 14, 2024 · 1 comment
Labels

Comments

@tredlich00
Copy link

tredlich00 commented Mar 14, 2024

I don't know if this qualifies as an issue but I was uncertain how to open a discussion.

I recently ran into an issue where everything appeared to be working correctly. I was pushing multiple files into my NOR flash SPI device and littlefs was doing just fine. Then, suddenly after the sixth or seventh test I could no longer mount the media.

I received the following sequence:
lfs.c:1366:error: Corrupted dir pair at {0x0, 0x1}
Mount Error, -84

I tried formatting and got:
lfs.c:2069:debug: Bad block at 0x0
lfs.c:2074:warn: Superblock 0x0 has become unwritable

At that point my code would fail and exit into my own error handling.

As I dug deeper I found some solutions that suggested I needed to erase my NOR flash device myself and that would correct the issue. As I built my code to do this I came to realize that there is a block_count variable in lfs_t and a block_count variable in struct lfs_config. The examples that I have found all show to link the *cfg pointer in struct lfs with the instance of struct lfs_config created in memory. This seemed logical to me and I did it. That leaves me with wondering why are there two separate block_count values in two structures linked to each other? The code in lfs.c uses both of them in various locations.

Yes, I am aware that it is very easy to just set them both equal to the same value and I have already done this. I am just curious if I am using it wrong and what the reason is for what appears to me as redundant variables?

@geky geky added the question label Mar 15, 2024
@geky
Copy link
Member

geky commented Mar 15, 2024

Hi @tredlich00 thanks for opening an issue. littlefs predates GitHub's discussions feature and I've been procrastinating on figuring out how that works, so that's on me (enabling discussions is irreversible).

As I built my code to do this I came to realize that there is a block_count variable in lfs_t and a block_count variable in struct lfs_config.

Ah, this is a bit of a limitation of C's "header-is-documentation". The documented struct lfs_config struct should be filled out when calling lfs_mount, but the undocumented lfs_t struct is an implementation detail that does not need to (shouldn't?) be filled out.

But lfs_t needs to be fully defined in the header file so C knows its size/alignment.


The technical reason block_count occurs twice:

You don't need to know the block count before mounting the disk. If struct lfs_config's block_count is 0, the actual block_count is read from metadata stored on disk.

We can't store this in struct lfs_config's block_count, because struct lfs_config is const, and may be stored in ROM. So the only option is a duplicated field.

Because of these duplicated fields, a ROM backed struct lfs_config is less appealing than it initially was, so in the future we may move to not requiring struct lfs_config to live as long as lfs_t. Though this may require a major version change.


As I dug deeper I found some solutions that suggested I needed to erase my NOR flash device myself and that would correct the issue.

I'm curious, what led you down this path? littlefs's lfs_format function should be stateless, unless the block device layers below littlefs has some weird external requirement.

Then, suddenly after the sixth or seventh test I could no longer mount the media.

This is all suggesting that the erase callback is not implemented correctly. Out of the factory, your device may be pre-erased, which would allow a small number of commits to be written. But then littlefs will need to erase a block for new commits, which could lead to this error. This would also explain why reformatting didn't work.

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

No branches or pull requests

2 participants