Skip to content

Commit 9b8f802

Browse files
fixup! Add support for shrinking a filesystem
1 parent 2105e50 commit 9b8f802

File tree

4 files changed

+40
-69
lines changed

4 files changed

+40
-69
lines changed

lfs.c

Lines changed: 31 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -5233,12 +5233,41 @@ static int lfs_fs_gc_(lfs_t *lfs) {
52335233
#endif
52345234

52355235
#ifndef LFS_READONLY
5236-
static int lfs_fs_rewrite_block_count(lfs_t *lfs, lfs_size_t block_count) {
5236+
#ifdef LFS_SHRINKIFCHEAP
5237+
static int lfs_shrink_checkblock(void * data, lfs_block_t block) {
5238+
lfs_size_t threshold = *((lfs_size_t *) data);
5239+
if (block >= threshold) {
5240+
return LFS_ERR_NOTEMPTY;
5241+
}
5242+
return 0;
5243+
}
5244+
#endif
5245+
5246+
static int lfs_fs_grow_(lfs_t *lfs, lfs_size_t block_count) {
5247+
int err;
5248+
5249+
if (block_count == lfs->block_count) {
5250+
return 0;
5251+
}
5252+
5253+
5254+
#ifndef LFS_SHRINKIFCHEAP
5255+
// shrinking is not supported
5256+
LFS_ASSERT(block_count >= lfs->block_count);
5257+
#endif
5258+
#ifdef LFS_SHRINKIFCHEAP
5259+
lfs_block_t threshold = block_count;
5260+
err = lfs_fs_traverse_(lfs, lfs_shrink_checkblock, &threshold, true);
5261+
if (err) {
5262+
return err;
5263+
}
5264+
#endif
5265+
52375266
lfs->block_count = block_count;
52385267

52395268
// fetch the root
52405269
lfs_mdir_t root;
5241-
int err = lfs_dir_fetch(lfs, &root, lfs->root);
5270+
err = lfs_dir_fetch(lfs, &root, lfs->root);
52425271
if (err) {
52435272
return err;
52445273
}
@@ -5263,41 +5292,6 @@ static int lfs_fs_rewrite_block_count(lfs_t *lfs, lfs_size_t block_count) {
52635292
}
52645293
return 0;
52655294
}
5266-
5267-
static int lfs_fs_grow_(lfs_t *lfs, lfs_size_t block_count) {
5268-
// shrinking is not supported
5269-
LFS_ASSERT(block_count >= lfs->block_count);
5270-
5271-
if (block_count > lfs->block_count) {
5272-
return lfs_fs_rewrite_block_count(lfs, block_count);
5273-
}
5274-
5275-
return 0;
5276-
}
5277-
5278-
static int lfs_shrink_check_block(void * data, lfs_block_t block) {
5279-
lfs_size_t threshold = *((lfs_size_t *) data);
5280-
if (block >= threshold) {
5281-
return LFS_ERR_NOTEMPTY;
5282-
}
5283-
return 0;
5284-
}
5285-
5286-
static int lfs_fs_shrink_(lfs_t *lfs, lfs_size_t block_count) {
5287-
if (block_count != lfs->block_count) {
5288-
5289-
lfs_block_t threshold = block_count;
5290-
5291-
int err = lfs_fs_traverse_(lfs, lfs_shrink_check_block, &threshold, true);
5292-
if (err) {
5293-
return err;
5294-
}
5295-
5296-
return lfs_fs_rewrite_block_count(lfs, block_count);
5297-
}
5298-
5299-
return 0;
5300-
}
53015295
#endif
53025296

53035297
#ifdef LFS_MIGRATE
@@ -6514,22 +6508,6 @@ int lfs_fs_grow(lfs_t *lfs, lfs_size_t block_count) {
65146508
}
65156509
#endif
65166510

6517-
#ifndef LFS_READONLY
6518-
int lfs_fs_shrink(lfs_t *lfs, lfs_size_t block_count) {
6519-
int err = LFS_LOCK(lfs->cfg);
6520-
if (err) {
6521-
return err;
6522-
}
6523-
LFS_TRACE("lfs_fs_shrink(%p, %"PRIu32")", (void*)lfs, block_count);
6524-
6525-
err = lfs_fs_shrink_(lfs, block_count);
6526-
6527-
LFS_TRACE("lfs_fs_shrink -> %d", err);
6528-
LFS_UNLOCK(lfs->cfg);
6529-
return err;
6530-
}
6531-
#endif
6532-
65336511
#ifdef LFS_MIGRATE
65346512
int lfs_migrate(lfs_t *lfs, const struct lfs_config *cfg) {
65356513
int err = LFS_LOCK(cfg);

lfs.h

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -766,23 +766,16 @@ int lfs_fs_gc(lfs_t *lfs);
766766
// Grows the filesystem to a new size, updating the superblock with the new
767767
// block count.
768768
//
769+
// if LFS_SHRINKIFCHEAP is defined, this function will also accept
770+
// block_counts smaller than the current configuration, after checking
771+
// that none of the blocks that are being removed are in use.
772+
//
769773
// Note: This is irreversible.
770774
//
771775
// Returns a negative error code on failure.
772776
int lfs_fs_grow(lfs_t *lfs, lfs_size_t block_count);
773777
#endif
774778

775-
#ifndef LFS_READONLY
776-
// Shrinks the filesystem to a new size, updating the superblock with the new
777-
// block count.
778-
//
779-
// Note: This first checks that none of the blocks that are being removed are in use
780-
// and will fail if it is the case
781-
//
782-
// Returns a negative error code on failure.
783-
int lfs_fs_shrink(lfs_t *lfs, lfs_size_t block_count);
784-
#endif
785-
786779
#ifndef LFS_READONLY
787780
#ifdef LFS_MIGRATE
788781
// Attempts to migrate a previous version of littlefs

tests/test_shrink.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ code = '''
77
lfs_t lfs;
88
lfs_format(&lfs, cfg) => 0;
99
lfs_mount(&lfs, cfg) => 0;
10-
lfs_fs_shrink(&lfs, AFTER_BLOCK_COUNT) => 0;
10+
lfs_fs_grow(&lfs, AFTER_BLOCK_COUNT) => 0;
1111
lfs_unmount(&lfs);
1212
if (BLOCK_COUNT != AFTER_BLOCK_COUNT) {
1313
lfs_mount(&lfs, cfg) => LFS_ERR_INVAL;
@@ -46,7 +46,7 @@ code = '''
4646
lfs_file_close(&lfs, &file) => 0;
4747
}
4848
49-
int err = lfs_fs_shrink(&lfs, AFTER_BLOCK_COUNT);
49+
int err = lfs_fs_grow(&lfs, AFTER_BLOCK_COUNT);
5050
if (err == 0) {
5151
for (int i = 0; i < FILES_COUNT + 1; i++) {
5252
lfs_file_t file;

tests/test_superblocks.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -550,7 +550,7 @@ code = '''
550550
551551
// same size is a noop
552552
lfs_mount(&lfs, cfg) => 0;
553-
lfs_fs_shrink(&lfs, BLOCK_COUNT) => 0;
553+
lfs_fs_grow(&lfs, BLOCK_COUNT) => 0;
554554
lfs_fs_stat(&lfs, &fsinfo) => 0;
555555
assert(fsinfo.block_size == BLOCK_SIZE);
556556
assert(fsinfo.block_count == BLOCK_COUNT);
@@ -564,7 +564,7 @@ code = '''
564564
565565
// grow to new size
566566
lfs_mount(&lfs, cfg) => 0;
567-
lfs_fs_shrink(&lfs, BLOCK_COUNT_2) => 0;
567+
lfs_fs_grow(&lfs, BLOCK_COUNT_2) => 0;
568568
lfs_fs_stat(&lfs, &fsinfo) => 0;
569569
assert(fsinfo.block_size == BLOCK_SIZE);
570570
assert(fsinfo.block_count == BLOCK_COUNT_2);
@@ -594,7 +594,7 @@ code = '''
594594
595595
// same size is a noop
596596
lfs_mount(&lfs, cfg) => 0;
597-
lfs_fs_shrink(&lfs, BLOCK_COUNT_2) => 0;
597+
lfs_fs_grow(&lfs, BLOCK_COUNT_2) => 0;
598598
lfs_fs_stat(&lfs, &fsinfo) => 0;
599599
assert(fsinfo.block_size == BLOCK_SIZE);
600600
assert(fsinfo.block_count == BLOCK_COUNT_2);

0 commit comments

Comments
 (0)