WIP moved superblock to entry append

This commit is contained in:
Christopher Haster
2018-03-23 16:11:36 -05:00
parent 66cdab8327
commit c5b11d2a62
4 changed files with 44 additions and 50 deletions

73
lfs.c
View File

@@ -2362,38 +2362,40 @@ int lfs_format(lfs_t *lfs, const struct lfs_config *cfg) {
lfs->root[0] = root.pair[0]; lfs->root[0] = root.pair[0];
lfs->root[1] = root.pair[1]; lfs->root[1] = root.pair[1];
superdir.d.tail[0] = lfs->root[0];
superdir.d.tail[1] = lfs->root[1];
// write superblocks // write one superblocks
lfs_superblock_t superblock = { lfs_superblock_t superblock;
.d.type = LFS_STRUCT_DIR | LFS_TYPE_SUPERBLOCK, superblock.d.version = LFS_DISK_VERSION,
.d.elen = sizeof(superblock.d) - sizeof(superblock.d.magic) - 4, superblock.d.root[0] = lfs->root[0];
.d.nlen = sizeof(superblock.d.magic), superblock.d.root[1] = lfs->root[1];
.d.version = LFS_DISK_VERSION, superblock.d.block_size = lfs->cfg->block_size;
.d.magic = {"littlefs"}, superblock.d.block_count = lfs->cfg->block_count;
.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 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); lfs_superblock_tole32(&superblock.d);
bool valid = false; err = lfs_dir_append(lfs, &superdir, &superentry,
for (int i = 0; i < 2; i++) { &(struct lfs_region){
err = lfs_dir_commit(lfs, &superdir, &(struct lfs_region){ 0, +4,
sizeof(superdir.d), 0, lfs_commit_mem, &superentry.d, 4,
lfs_commit_mem, &superblock.d, sizeof(superblock.d)}); &(struct lfs_region){
if (err && err != LFS_ERR_CORRUPT) { 0, +sizeof(superblock.d),
return err; lfs_commit_mem, &superblock.d, sizeof(superblock.d),
} &(struct lfs_region){
0, +superentry.d.nlen,
valid = valid || !err; lfs_commit_mem, "littlefs", superentry.d.nlen}}});
} if (err) {
return err;
if (!valid) {
return LFS_ERR_CORRUPT;
} }
// sanity check that fetch works // sanity check that fetch works
@@ -2402,7 +2404,6 @@ int lfs_format(lfs_t *lfs, const struct lfs_config *cfg) {
return err; return err;
} }
lfs_alloc_ack(lfs);
return lfs_deinit(lfs); return lfs_deinit(lfs);
} }
@@ -2421,24 +2422,32 @@ int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) {
// load superblock // load superblock
lfs_dir_t dir; lfs_dir_t dir;
lfs_superblock_t superblock; lfs_superblock_t superblock;
char magic[8];
err = lfs_dir_fetch(lfs, &dir, (const lfs_block_t[2]){0, 1}); err = lfs_dir_fetch(lfs, &dir, (const lfs_block_t[2]){0, 1});
if (err && err != LFS_ERR_CORRUPT) { if (err && err != LFS_ERR_CORRUPT) {
return err; return err;
} }
if (!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)); &superblock.d, sizeof(superblock.d));
lfs_superblock_fromle32(&superblock.d); lfs_superblock_fromle32(&superblock.d);
if (err) { if (err) {
return 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[0] = superblock.d.root[0];
lfs->root[1] = superblock.d.root[1]; lfs->root[1] = superblock.d.root[1];
} }
if (err || memcmp(superblock.d.magic, "littlefs", 8) != 0) { if (err || memcmp(magic, "littlefs", 8) != 0) {
LFS_ERROR("Invalid superblock at %d %d", dir.pair[0], dir.pair[1]); LFS_ERROR("Invalid superblock at %d %d", dir.pair[0], dir.pair[1]);
return LFS_ERR_CORRUPT; return LFS_ERR_CORRUPT;
} }

5
lfs.h
View File

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

View File

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

View File

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