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

Infer block_count from superblock if not provided in config. #866

Merged
merged 16 commits into from
Sep 21, 2023

Conversation

BrianPugh
Copy link
Contributor

@BrianPugh BrianPugh commented Aug 17, 2023

This pull request attempts to autodetect the block_count from the superblock if not provided in lfs_config (i.e. cfg->block_count == 0).

This PR slightly increases RAM usage by increasing the lfs_t struct by 4 bytes.

I think this PR could also negatively impact mounting performance (I refactored it so that the superblock search and the gstate search are independent), but I think those are super fast anyways. A possible organization improvement would be to abstract the traversal to another function, but that might reduce readability. We can leave that for another PR.

@geky currently this is set as a draft as I want to write more unit tests, but need some advice on how to debug. Currently one of the test permutations hangs; I don't quite understand what the permutations are or how to debug.

Related issues & PRs: #865, #753

For ease of review, the biggest commit (7328527) just moves the identical traversal into 2 functions (superblock, gstate), and moves the superblock validation to a separate function. There's no real logic change in that commit, except that the superblock is found first, then the gstate is updated (rather than at the same time).

@BrianPugh BrianPugh marked this pull request as ready for review August 18, 2023 02:56
@BrianPugh
Copy link
Contributor Author

@geky I think this is ready now!

@geky-bot
Copy link
Collaborator

Tests passed ✓, Code: 16898 B (+1.4%), Stack: 1432 B (+0.0%), Structs: 792 B (+0.5%)
Code Stack Structs Coverage
Default 16898 B (+1.4%) 1432 B (+0.0%) 792 B (+0.5%) Lines 2344/2523 lines (+0.1%)
Readonly 6298 B (+2.8%) 448 B (+0.0%) 792 B (+0.5%) Branches 1210/1536 branches (+0.2%)
Threadsafe 17730 B (+1.3%) 1432 B (+0.0%) 800 B (+0.5%) Benchmarks
Multiversion 16958 B (+1.3%) 1432 B (+0.0%) 796 B (+0.5%) Readed 29370160748 B (+0.0%)
Migrate 18590 B (+1.3%) 1736 B (+0.0%) 796 B (+0.5%) Proged 1482874766 B (+0.0%)
Error-asserts 17538 B (+1.4%) 1424 B (+0.0%) 792 B (+0.5%) Erased 1568888832 B (+0.0%)

@BrianPugh
Copy link
Contributor Author

what are our thoughts on this? It's less invasive than the other PRs. It's also a backwards compatible change. Any future changes (such as if we allow lfs_config_t to be mutable) are compatible with this PR. In that example, we'd just remove the newly introduced lfs->block_count field and have all the pointers point back to the now mutable lfs->config->block_count.

I'm looking forward to some form of block_count autodetection so that I can publish my cli tool that manages littlefs partitions to PyPI.

@geky geky added enhancement needs minor version new functionality only allowed in minor versions labels Aug 20, 2023
@geky
Copy link
Member

geky commented Aug 20, 2023

Hi @BrianPugh, thanks for this. I left some feedback.

I'm not sure fetching the block_count from disk during lfs_format makes sense. I left an in-code comment about that.

I think we should also add block_count (and maybe block_size for completeness) to lfs_fs_stat, so the block_count is available to the user after mounting. This should just mean another assignment in lfs_fs_rawstat: here.

I'm also curious if the test_superblocks_fewer_blocks and test_superblocks_more_blocks tests from #753 can be ported over to this. They provide coverage for a few more corner cases, and should cover changes to lfs_fs_stat well enough.


I'm also thinking I'll try to get lfs_fs_grow (#753, #702) in on the same minor release as this, since they are closely related. Though that doesn't affect this PR.

Copy link
Member

@geky geky left a comment

Choose a reason for hiding this comment

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

Whoops, mixed up normal comments and review comments...

Now it should have some feedback.

lfs.c Outdated Show resolved Hide resolved
lfs.c Outdated Show resolved Hide resolved
lfs.c Outdated Show resolved Hide resolved
lfs.c Outdated Show resolved Hide resolved
@geky
Copy link
Member

geky commented Aug 20, 2023

@geky currently this is set as a draft as I want to write more unit tests, but need some advice on how to debug. Currently one of the test permutations hangs; I don't quite understand what the permutations are or how to debug.

Were you able to figure out debugging with the test framework? It's unfortunately a bit dense not documented well.

If a test permutation fails in CI:

tests/test_compat.toml:1296:failure: test_compat_major_incompat:1g12gg2 (PROG_SIZE=16, BLOCK_SIZE=512) failed 

You should be able to rerun it locally like so:

# build the test runner
$ make test-runner -j
# run the failing test
$ ./scripts/test.py runners/test_runner test_compat_major_incompat:1g12gg2

Though for the Valgrind tests you need to pass the valgrind flag:

$ ./scripts/test.py runners/test_runner test_compat_major_incompat:1g12gg2 --valgrind

Note the test framework expects quite a bit more from the dev environment than littlefs itself. It's unlikely to work with a non-GCC/Clang compiler...

@BrianPugh
Copy link
Contributor Author

I'll add the lfs_fs_stat functionality and investigate the unit tests you recommended

@geky-bot
Copy link
Collaborator

Tests passed ✓, Code: 16898 B (+1.4%), Stack: 1432 B (+0.0%), Structs: 792 B (+0.5%)
Code Stack Structs Coverage
Default 16898 B (+1.4%) 1432 B (+0.0%) 792 B (+0.5%) Lines 2345/2524 lines (+0.1%)
Readonly 6298 B (+2.8%) 448 B (+0.0%) 792 B (+0.5%) Branches 1210/1536 branches (+0.2%)
Threadsafe 17730 B (+1.3%) 1432 B (+0.0%) 800 B (+0.5%) Benchmarks
Multiversion 16958 B (+1.3%) 1432 B (+0.0%) 796 B (+0.5%) Readed 29370160748 B (+0.0%)
Migrate 18574 B (+1.2%) 1736 B (+0.0%) 796 B (+0.5%) Proged 1482874766 B (+0.0%)
Error-asserts 17538 B (+1.4%) 1424 B (+0.0%) 792 B (+0.5%) Erased 1568888832 B (+0.0%)

@geky-bot
Copy link
Collaborator

Tests passed ✓, Code: 16906 B (+1.4%), Stack: 1432 B (+0.0%), Structs: 800 B (+1.5%)
Code Stack Structs Coverage
Default 16906 B (+1.4%) 1432 B (+0.0%) 800 B (+1.5%) Lines 2347/2526 lines (+0.1%)
Readonly 6306 B (+2.9%) 448 B (+0.0%) 800 B (+1.5%) Branches 1210/1536 branches (+0.2%)
Threadsafe 17738 B (+1.4%) 1432 B (+0.0%) 808 B (+1.5%) Benchmarks
Multiversion 16966 B (+1.3%) 1432 B (+0.0%) 804 B (+1.5%) Readed 29370160748 B (+0.0%)
Migrate 18582 B (+1.3%) 1736 B (+0.0%) 804 B (+1.5%) Proged 1482874766 B (+0.0%)
Error-asserts 17546 B (+1.4%) 1424 B (+0.0%) 800 B (+1.5%) Erased 1568888832 B (+0.0%)

@BrianPugh
Copy link
Contributor Author

@geky-bot copying over the tests from #753 ALMOST works, but it would also involve copying over all the runner and related changes. I feel like that might balloon this PR and make a bunch of unnecessary merge conflicts. Waiting for your advice before performing more actions.

Since your last review I:

  • Updated lfs_fs_stat along with the related struct fields.
  • Fixed linting.

@BrianPugh BrianPugh requested a review from geky August 20, 2023 19:29
@geky-bot
Copy link
Collaborator

Tests passed ✓, Code: 16794 B (+0.8%), Stack: 1432 B (+0.0%), Structs: 800 B (+1.5%)
Code Stack Structs Coverage
Default 16794 B (+0.8%) 1432 B (+0.0%) 800 B (+1.5%) Lines 2341/2518 lines (+0.2%)
Readonly 6306 B (+2.9%) 448 B (+0.0%) 800 B (+1.5%) Branches 1206/1532 branches (+0.1%)
Threadsafe 17634 B (+0.8%) 1432 B (+0.0%) 808 B (+1.5%) Benchmarks
Multiversion 16854 B (+0.7%) 1432 B (+0.0%) 804 B (+1.5%) Readed 29370160748 B (+0.0%)
Migrate 18470 B (+0.7%) 1736 B (+0.0%) 804 B (+1.5%) Proged 1482874766 B (+0.0%)
Error-asserts 17450 B (+0.9%) 1424 B (+0.0%) 800 B (+1.5%) Erased 1568888832 B (+0.0%)

@BrianPugh
Copy link
Contributor Author

so whats the conclusion on this? Does the PR seem good? Waiting to bundle it with other PRs for a release?

@geky
Copy link
Member

geky commented Sep 3, 2023

This is looking good, thanks for the updates. I'm currently planning to bring this in on the next minor release.

I'm still wanting to look into the extra tests in #753, which as you point likely come with baggage, and lfs_fs_grow (#753, #702) since it is closely related. But I think these would be more appropriate in separate PRs.

This would result in two passes through the superblock chain during
mount, when we can access everything we need to in one.
@geky
Copy link
Member

geky commented Sep 3, 2023

I've gone ahead and reverted the lfs_scan_for_superblocks and lfs_scan_for_state_updates refactor. The new code path would have led to scanning the superblock chain twice, when we only need to scan it once.

Let me know if you see anything wrong with this.

@geky-bot
Copy link
Collaborator

geky-bot commented Sep 3, 2023

Tests passed ✓, Code: 16674 B (-0.0%), Stack: 1432 B (+0.0%), Structs: 800 B (+1.5%)
Code Stack Structs Coverage
Default 16674 B (-0.0%) 1432 B (+0.0%) 800 B (+1.5%) Lines 2319/2497 lines (+0.1%)
Readonly 6130 B (+0.1%) 448 B (+0.0%) 800 B (+1.5%) Branches 1193/1516 branches (+0.1%)
Threadsafe 17506 B (+0.0%) 1432 B (+0.0%) 808 B (+1.5%) Benchmarks
Multiversion 16734 B (-0.1%) 1432 B (+0.0%) 804 B (+1.5%) Readed 29369693876 B (+0.0%)
Migrate 18350 B (-0.1%) 1736 B (+0.0%) 804 B (+1.5%) Proged 1482874766 B (+0.0%)
Error-asserts 17330 B (+0.1%) 1424 B (+0.0%) 800 B (+1.5%) Erased 1568888832 B (+0.0%)

@BrianPugh
Copy link
Contributor Author

BrianPugh commented Sep 3, 2023

@geky that's fine by me since we no longer invoke lfs_scan_for_superblocks at multiple places 👍 . It also does make this PR a lot more terse :D

In separating the configuration of littlefs from the physical geometry
of the underlying device, we can no longer rely solely on lfs_config to
contain all of the information necessary for the simulated block devices
we use for testing.

This adds a new lfs_*bd_config struct for each of the block devices, and
new erase_size/erase_count fields. The erase_* name was chosen since
these reflect the (simulated) physical erase size and count of
erase-sized blocks, unlike the block_* variants which represent logical
block sizes used for littlefs's bookkeeping.

It may be worth adopting erase_size/erase_count in littlefs's config at
some point in the future, but at the moment doesn't seem necessary.

Changing the lfs_bd_config structs to be required is probably a good
idea anyways, as it moves us more towards separating the bds from
littlefs. Though we can't quite get rid of the lfs_config parameter
because of the block-device API in lfs_config. Eventually it would be
nice to get rid of it, but that would require API breakage.
@geky
Copy link
Member

geky commented Sep 12, 2023

I've also gone ahead and adopted the block-device/runner changes in #753. I realize this is probably pushing the scope of this PR, but it lets us adopt the tests in #753, and is probably a good long-term change.

I also tweaked lfs_fsinfo a bit, mainly to make the struct fields follow the order found in the superblock for consistency. I realize this is really nitpicky.

If you're ok with these changes this looks good to me for the next minor release.

@geky geky added next minor and removed needs minor version new functionality only allowed in minor versions labels Sep 12, 2023
@geky
Copy link
Member

geky commented Sep 12, 2023

Also the now-dependent lfs_fs_grow API is here: #872

These were cherry-picked from some previous work on a related feature.
Mainly to match superblock ordering and emphasize these are logical
blocks.
@geky-bot
Copy link
Collaborator

Tests passed ✓, Code: 16686 B (+0.0%), Stack: 1432 B (+0.0%), Structs: 800 B (+1.5%)
Code Stack Structs Coverage
Default 16686 B (+0.0%) 1432 B (+0.0%) 800 B (+1.5%) Lines 2323/2498 lines (+0.2%)
Readonly 6130 B (+0.1%) 448 B (+0.0%) 800 B (+1.5%) Branches 1194/1516 branches (+0.2%)
Threadsafe 17518 B (+0.1%) 1432 B (+0.0%) 808 B (+1.5%) Benchmarks
Multiversion 16746 B (-0.0%) 1432 B (+0.0%) 804 B (+1.5%) Readed 29369693876 B (+0.0%)
Migrate 18362 B (+0.0%) 1736 B (+0.0%) 804 B (+1.5%) Proged 1482874766 B (+0.0%)
Error-asserts 17338 B (+0.2%) 1424 B (+0.0%) 800 B (+1.5%) Erased 1568888832 B (+0.0%)

@BrianPugh
Copy link
Contributor Author

all seems good to me!

@geky geky changed the base branch from master to devel September 21, 2023 17:06
@geky geky merged commit e4b7fa1 into littlefs-project:devel Sep 21, 2023
16 checks passed
@geky geky mentioned this pull request Sep 21, 2023
@geky
Copy link
Member

geky commented Jan 23, 2024

This is on master now, thanks for the PR!

@geky
Copy link
Member

geky commented Jan 23, 2024

Whoops, meant to respond to this one: #886. Well this is technically on master as well so...

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

Successfully merging this pull request may close these issues.

3 participants