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

Add lfs_fs_grow to enable limited resizing of the filesystem #872

Merged
merged 17 commits into from
Sep 21, 2023
Merged

Conversation

geky
Copy link
Member

@geky geky commented Sep 12, 2023

Originally proposed by @kaetemi, this API allows you to change the size of the filesystem on disk to take advantage of additional space if it becomes available:

 cfg.block_count = 1024;
 
 int err = lfs_mount(lfs, cfg);
 if (err) {
     return err;
 }
 
 struct lfs_fsstat fsstat;
 err = lfs_fs_stat(lfs, &fsstat);
 if (err) {
     return err;
 }
 printf("block_count: %d\n", fsstat.block_count); // prints 1024
 
 err = lfs_fs_grow(lfs, 2048);
 if (err) {
     return err;
 }
 
 struct lfs_fsstat fsstat;
 err = lfs_fs_stat(lfs, &fsstat);
 if (err) {
     return err;
 }
 printf("block_count: %d\n", fsstat.block_count); // prints 2048

If you want to automatically resize littlefs to the full disk size every mount, this can be done by using these two calls as your "mount" operation:

lfs_size_t required_block_count = DISK_SIZE / BLOCK_SIZE;

// unknown block_count
cfg.block_count = 0;

// mount and resize if disk has grown
int err = lfs_mount(lfs, cfg);
if (err) {
    return err;
}

err = lfs_fs_grow(lfs, required_block_count);
if (err) {
    return err;
}

See #702, #279, and #753 for related discussions.

This depends on #866, which makes block_size optional

BrianPugh and others added 14 commits August 16, 2023 22:23
Some block-device bound-checks are disabled during superblock search.
This would result in two passes through the superblock chain during
mount, when we can access everything we need to in one.
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.
These were cherry-picked from some previous work on a related feature.
Mainly to match superblock ordering and emphasize these are logical
blocks.
The initial implementation for this was provided by kaetemi, originally
as a mount flag. However, it has been modified here to be self-contained
in an explicit runtime function that can be called after mount.

The reasons for an explicit function:

1. lfs_mount stays a strictly readonly operation, and avoids pulling in
   all of the write machinery.

2. filesystem-wide operations such as lfs_fs_grow can be a bit risky,
   and irreversable. The action of growing the filesystem should be very
   intentional.

---

One concern with this change is that this will be the first function
that changes metadata in the superblock. This might break tools that
expect the first valid superblock entry to contain the most recent
metadata, since only the last superblock in the superblock chain will
contain the updated metadata.
@geky-bot
Copy link
Collaborator

Tests passed ✓, Code: 16810 B (+0.8%), Stack: 1432 B (+0.0%), Structs: 800 B (+1.5%)
Code Stack Structs Coverage
Default 16810 B (+0.8%) 1432 B (+0.0%) 800 B (+1.5%) Lines 2346/2522 lines (+0.2%)
Readonly 6130 B (+0.1%) 448 B (+0.0%) 800 B (+1.5%) Branches 1200/1526 branches (-0.0%)
Threadsafe 17670 B (+0.9%) 1432 B (+0.0%) 808 B (+1.5%) Benchmarks
Multiversion 16870 B (+0.7%) 1432 B (+0.0%) 804 B (+1.5%) Readed 29369693876 B (+0.0%)
Migrate 18486 B (+0.7%) 1736 B (+0.0%) 804 B (+1.5%) Proged 1482874766 B (+0.0%)
Error-asserts 17470 B (+0.9%) 1424 B (+0.0%) 800 B (+1.5%) Erased 1568888832 B (+0.0%)

@geky geky changed the base branch from master to devel September 21, 2023 17:06
@geky geky merged commit 1ba4ed0 into devel Sep 21, 2023
32 checks passed
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