فهرست منبع

fixup! Add support for shrinking a filesystem

Sosthène Guédon 7 ماه پیش
والد
کامیت
9b8f802b43
4فایلهای تغییر یافته به همراه40 افزوده شده و 69 حذف شده
  1. 31 53
      lfs.c
  2. 4 11
      lfs.h
  3. 2 2
      tests/test_shrink.toml
  4. 3 3
      tests/test_superblocks.toml

+ 31 - 53
lfs.c

@@ -5233,12 +5233,41 @@ static int lfs_fs_gc_(lfs_t *lfs) {
 #endif
 
 #ifndef LFS_READONLY
-static int lfs_fs_rewrite_block_count(lfs_t *lfs, lfs_size_t block_count) {
+#ifdef LFS_SHRINKIFCHEAP
+static int lfs_shrink_checkblock(void * data, lfs_block_t block) {
+    lfs_size_t threshold = *((lfs_size_t *) data);
+    if (block >= threshold) {
+        return LFS_ERR_NOTEMPTY;
+    }
+    return 0;
+}
+#endif
+
+static int lfs_fs_grow_(lfs_t *lfs, lfs_size_t block_count) {
+    int err;
+
+    if (block_count == lfs->block_count) {
+        return 0;
+    }
+
+    
+#ifndef LFS_SHRINKIFCHEAP
+    // shrinking is not supported
+    LFS_ASSERT(block_count >= lfs->block_count);
+#endif
+#ifdef LFS_SHRINKIFCHEAP
+    lfs_block_t threshold = block_count;
+    err = lfs_fs_traverse_(lfs, lfs_shrink_checkblock, &threshold, true);
+    if (err) {
+        return err;
+    }
+#endif
+
     lfs->block_count = block_count;
 
     // fetch the root
     lfs_mdir_t root;
-    int err = lfs_dir_fetch(lfs, &root, lfs->root);
+    err = lfs_dir_fetch(lfs, &root, lfs->root);
     if (err) {
         return err;
     }
@@ -5263,41 +5292,6 @@ static int lfs_fs_rewrite_block_count(lfs_t *lfs, lfs_size_t block_count) {
     }
     return 0;
 }
-
-static int lfs_fs_grow_(lfs_t *lfs, lfs_size_t block_count) {
-    // shrinking is not supported
-    LFS_ASSERT(block_count >= lfs->block_count);
-
-    if (block_count > lfs->block_count) {
-        return lfs_fs_rewrite_block_count(lfs, block_count);
-    }
-
-    return 0;
-}
-
-static int lfs_shrink_check_block(void * data, lfs_block_t block) {
-    lfs_size_t threshold = *((lfs_size_t *) data);
-    if (block >= threshold) {
-        return LFS_ERR_NOTEMPTY;
-    }
-    return 0;
-}
-
-static int lfs_fs_shrink_(lfs_t *lfs, lfs_size_t block_count) {
-    if (block_count != lfs->block_count) {
-
-        lfs_block_t threshold = block_count;
-
-        int err = lfs_fs_traverse_(lfs, lfs_shrink_check_block, &threshold, true);
-        if (err) {
-            return err;
-        }
-
-        return lfs_fs_rewrite_block_count(lfs, block_count);
-    }
-
-    return 0;
-}
 #endif
 
 #ifdef LFS_MIGRATE
@@ -6514,22 +6508,6 @@ int lfs_fs_grow(lfs_t *lfs, lfs_size_t block_count) {
 }
 #endif
 
-#ifndef LFS_READONLY
-int lfs_fs_shrink(lfs_t *lfs, lfs_size_t block_count) {
-    int err = LFS_LOCK(lfs->cfg);
-    if (err) {
-        return err;
-    }
-    LFS_TRACE("lfs_fs_shrink(%p, %"PRIu32")", (void*)lfs, block_count);
-
-    err = lfs_fs_shrink_(lfs, block_count);
-
-    LFS_TRACE("lfs_fs_shrink -> %d", err);
-    LFS_UNLOCK(lfs->cfg);
-    return err;
-}
-#endif
-
 #ifdef LFS_MIGRATE
 int lfs_migrate(lfs_t *lfs, const struct lfs_config *cfg) {
     int err = LFS_LOCK(cfg);

+ 4 - 11
lfs.h

@@ -766,23 +766,16 @@ int lfs_fs_gc(lfs_t *lfs);
 // Grows the filesystem to a new size, updating the superblock with the new
 // block count.
 //
+// if LFS_SHRINKIFCHEAP is defined, this function will also accept
+// block_counts smaller than the current configuration, after checking
+// that none of the blocks that are being removed are in use.
+//
 // Note: This is irreversible.
 //
 // Returns a negative error code on failure.
 int lfs_fs_grow(lfs_t *lfs, lfs_size_t block_count);
 #endif
 
-#ifndef LFS_READONLY
-// Shrinks the filesystem to a new size, updating the superblock with the new
-// block count.
-//
-// Note: This first checks that none of the blocks that are being removed are in use
-// and will fail if it is the case
-//
-// Returns a negative error code on failure.
-int lfs_fs_shrink(lfs_t *lfs, lfs_size_t block_count);
-#endif
-
 #ifndef LFS_READONLY
 #ifdef LFS_MIGRATE
 // Attempts to migrate a previous version of littlefs

+ 2 - 2
tests/test_shrink.toml

@@ -7,7 +7,7 @@ code = '''
     lfs_t lfs;
     lfs_format(&lfs, cfg) => 0;
     lfs_mount(&lfs, cfg) => 0;
-    lfs_fs_shrink(&lfs, AFTER_BLOCK_COUNT) => 0;
+    lfs_fs_grow(&lfs, AFTER_BLOCK_COUNT) => 0;
     lfs_unmount(&lfs);
     if (BLOCK_COUNT != AFTER_BLOCK_COUNT) {
         lfs_mount(&lfs, cfg) => LFS_ERR_INVAL;
@@ -46,7 +46,7 @@ code = '''
         lfs_file_close(&lfs, &file) => 0;
     }
 
-    int err = lfs_fs_shrink(&lfs, AFTER_BLOCK_COUNT);
+    int err = lfs_fs_grow(&lfs, AFTER_BLOCK_COUNT);
     if (err == 0) {
         for (int i = 0; i < FILES_COUNT + 1; i++) {
             lfs_file_t file;

+ 3 - 3
tests/test_superblocks.toml

@@ -550,7 +550,7 @@ code = '''
 
     // same size is a noop
     lfs_mount(&lfs, cfg) => 0;
-    lfs_fs_shrink(&lfs, BLOCK_COUNT) => 0;
+    lfs_fs_grow(&lfs, BLOCK_COUNT) => 0;
     lfs_fs_stat(&lfs, &fsinfo) => 0;
     assert(fsinfo.block_size == BLOCK_SIZE);
     assert(fsinfo.block_count == BLOCK_COUNT);
@@ -564,7 +564,7 @@ code = '''
 
     // grow to new size
     lfs_mount(&lfs, cfg) => 0;
-    lfs_fs_shrink(&lfs, BLOCK_COUNT_2) => 0;
+    lfs_fs_grow(&lfs, BLOCK_COUNT_2) => 0;
     lfs_fs_stat(&lfs, &fsinfo) => 0;
     assert(fsinfo.block_size == BLOCK_SIZE);
     assert(fsinfo.block_count == BLOCK_COUNT_2);
@@ -594,7 +594,7 @@ code = '''
 
     // same size is a noop
     lfs_mount(&lfs, cfg) => 0;
-    lfs_fs_shrink(&lfs, BLOCK_COUNT_2) => 0;
+    lfs_fs_grow(&lfs, BLOCK_COUNT_2) => 0;
     lfs_fs_stat(&lfs, &fsinfo) => 0;
     assert(fsinfo.block_size == BLOCK_SIZE);
     assert(fsinfo.block_count == BLOCK_COUNT_2);