소스 검색

Changed how we write out superblock to use append

Making the superblock look like "just another entry" allows us to treat
the superblock like "just another entry" and reuse a decent amount of
logic that would otherwise only be used a format and mount time. In this
case we can use append to write out the superblock like it was creating
a new entry on the filesystem.
Christopher Haster 7 년 전
부모
커밋
d0e0453651
4개의 변경된 파일46개의 추가작업 그리고 52개의 파일을 삭제
  1. 43 34
      lfs.c
  2. 0 5
      lfs.h
  3. 2 2
      tests/test_corrupt.sh
  4. 1 11
      tests/test_format.sh

+ 43 - 34
lfs.c

@@ -2372,38 +2372,40 @@ int lfs_format(lfs_t *lfs, const struct lfs_config *cfg) {
 
     lfs->root[0] = root.pair[0];
     lfs->root[1] = root.pair[1];
+    superdir.d.tail[0] = lfs->root[0];
+    superdir.d.tail[1] = lfs->root[1];
 
-    // write superblocks
-    lfs_superblock_t superblock = {
-        .d.type = LFS_STRUCT_DIR | LFS_TYPE_SUPERBLOCK,
-        .d.elen = sizeof(superblock.d) - sizeof(superblock.d.magic) - 4,
-        .d.nlen = sizeof(superblock.d.magic),
-        .d.version = LFS_DISK_VERSION,
-        .d.magic = {"littlefs"},
-        .d.block_size  = lfs->cfg->block_size,
-        .d.block_count = lfs->cfg->block_count,
-        .d.root = {lfs->root[0], lfs->root[1]},
-    };
-    superdir.d.tail[0] = root.pair[0];
-    superdir.d.tail[1] = root.pair[1];
-    superdir.d.size = sizeof(superdir.d) + sizeof(superblock.d) + 4;
-
-    // write both pairs to be safe
+    // write one superblocks
+    lfs_superblock_t superblock;
+    superblock.d.version = LFS_DISK_VERSION,
+    superblock.d.root[0] = lfs->root[0];
+    superblock.d.root[1] = lfs->root[1];
+    superblock.d.block_size  = lfs->cfg->block_size;
+    superblock.d.block_count = lfs->cfg->block_count;
+
+    lfs_entry_t superentry;
+    superentry.d.type = LFS_STRUCT_DIR | LFS_TYPE_SUPERBLOCK;
+    superentry.d.elen = sizeof(superblock.d);
+    superentry.d.alen = 0;
+    superentry.d.nlen = strlen("littlefs");
+    superentry.off = sizeof(superdir.d);
+    superentry.size = 4 + superentry.d.elen +
+            superentry.d.alen + superentry.d.nlen;
+
+    lfs_entry_tole32(&superentry.d);
     lfs_superblock_tole32(&superblock.d);
-    bool valid = false;
-    for (int i = 0; i < 2; i++) {
-        err = lfs_dir_commit(lfs, &superdir, &(struct lfs_region){
-                sizeof(superdir.d), 0,
-                lfs_commit_mem, &superblock.d, sizeof(superblock.d)});
-        if (err && err != LFS_ERR_CORRUPT) {
-            return err;
-        }
-
-        valid = valid || !err;
-    }
-
-    if (!valid) {
-        return LFS_ERR_CORRUPT;
+    err = lfs_dir_append(lfs, &superdir, &superentry,
+            &(struct lfs_region){
+                0, +4,
+                lfs_commit_mem, &superentry.d, 4,
+            &(struct lfs_region){
+                0, +sizeof(superblock.d),
+                lfs_commit_mem, &superblock.d, sizeof(superblock.d),
+            &(struct lfs_region){
+                0, +superentry.d.nlen,
+                lfs_commit_mem, "littlefs", superentry.d.nlen}}});
+    if (err) {
+        return err;
     }
 
     // sanity check that fetch works
@@ -2412,7 +2414,6 @@ int lfs_format(lfs_t *lfs, const struct lfs_config *cfg) {
         return err;
     }
 
-    lfs_alloc_ack(lfs);
     return lfs_deinit(lfs);
 }
 
@@ -2431,25 +2432,33 @@ int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) {
     // load superblock
     lfs_dir_t dir;
     lfs_superblock_t superblock;
+    char magic[8];
     err = lfs_dir_fetch(lfs, &dir, (const lfs_block_t[2]){0, 1});
     if (err && err != LFS_ERR_CORRUPT) {
         return err;
     }
 
     if (!err) {
-        err = lfs_bd_read(lfs, dir.pair[0], sizeof(dir.d),
+        err = lfs_bd_read(lfs, dir.pair[0], sizeof(dir.d)+4,
                 &superblock.d, sizeof(superblock.d));
         lfs_superblock_fromle32(&superblock.d);
         if (err) {
             return err;
         }
 
+        err = lfs_bd_read(lfs, dir.pair[0],
+                sizeof(dir.d) + 4 + sizeof(superblock.d),
+                magic, sizeof(magic));
+        if (err) {
+            return err;
+        }
+
         lfs->root[0] = superblock.d.root[0];
         lfs->root[1] = superblock.d.root[1];
     }
 
-    if (err || memcmp(superblock.d.magic, "littlefs", 8) != 0) {
-        LFS_ERROR("Invalid superblock at %d %d", 0, 1);
+    if (err || memcmp(magic, "littlefs", 8) != 0) {
+        LFS_ERROR("Invalid superblock at %d %d", dir.pair[0], dir.pair[1]);
         return LFS_ERR_CORRUPT;
     }
 

+ 0 - 5
lfs.h

@@ -257,15 +257,10 @@ typedef struct lfs_dir {
 
 typedef struct lfs_superblock {
     struct lfs_disk_superblock {
-        uint8_t type;
-        uint8_t elen;
-        uint8_t alen;
-        uint8_t nlen;
         lfs_block_t root[2];
         uint32_t block_size;
         uint32_t block_count;
         uint32_t version;
-        char magic[8];
     } d;
 } lfs_superblock_t;
 

+ 2 - 2
tests/test_corrupt.sh

@@ -73,7 +73,7 @@ lfs_mktree
 lfs_chktree
 
 echo "--- Block corruption ---"
-for i in {0..33}
+for i in {2..33}
 do 
     rm -rf blocks
     mkdir blocks
@@ -83,7 +83,7 @@ do
 done
 
 echo "--- Block persistance ---"
-for i in {0..33}
+for i in {2..33}
 do 
     rm -rf blocks
     mkdir blocks

+ 1 - 11
tests/test_format.sh

@@ -30,20 +30,10 @@ echo "--- Invalid mount ---"
 tests/test.py << TEST
     lfs_format(&lfs, &cfg) => 0;
 TEST
-rm blocks/0 blocks/1
+rm -f blocks/0 blocks/1
 tests/test.py << TEST
     lfs_mount(&lfs, &cfg) => LFS_ERR_CORRUPT;
 TEST
 
-echo "--- Valid corrupt mount ---"
-tests/test.py << TEST
-    lfs_format(&lfs, &cfg) => 0;
-TEST
-rm blocks/0
-tests/test.py << TEST
-    lfs_mount(&lfs, &cfg) => 0;
-    lfs_unmount(&lfs) => 0;
-TEST
-
 echo "--- Results ---"
 tests/stats.py