Added more block_size/count inference tests and fixed a couple bugs
- Need to drop cache during block_size search. - Removed "Corrupted" messages when root is not found to avoid too much debug output. This also gets rid of a long-term point of confusion arround "Corrupted" messages on a mount that is intended to fail.
This commit is contained in:
@@ -1299,8 +1299,10 @@ static lfs_stag_t lfs_dir_fetchmatch(lfs_t *lfs,
|
|||||||
dir->rev = revs[(r+1)%2];
|
dir->rev = revs[(r+1)%2];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!lfs_pair_isnull(lfs->root)) {
|
||||||
LFS_ERROR("Corrupted dir pair at {0x%"PRIx32", 0x%"PRIx32"}",
|
LFS_ERROR("Corrupted dir pair at {0x%"PRIx32", 0x%"PRIx32"}",
|
||||||
dir->pair[0], dir->pair[1]);
|
dir->pair[0], dir->pair[1]);
|
||||||
|
}
|
||||||
return LFS_ERR_CORRUPT;
|
return LFS_ERR_CORRUPT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4231,6 +4233,10 @@ static int lfs_rawmount(lfs_t *lfs, const struct lfs_config *cfg) {
|
|||||||
lfs->block_count /= lfs->block_size/lfs->erase_size;
|
lfs->block_count /= lfs->block_size/lfs->erase_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// make sure cached data from a different block_size doesn't cause
|
||||||
|
// problems, we should never visit the same mdir twice here anyways
|
||||||
|
lfs_cache_drop(lfs, &lfs->rcache);
|
||||||
|
|
||||||
// scan directory blocks for superblock and any global updates
|
// scan directory blocks for superblock and any global updates
|
||||||
lfs_mdir_t dir = {.tail = {0, 1}};
|
lfs_mdir_t dir = {.tail = {0, 1}};
|
||||||
lfs_block_t cycle = 0;
|
lfs_block_t cycle = 0;
|
||||||
|
|||||||
+365
-58
@@ -150,89 +150,54 @@ code = '''
|
|||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
# mount with unknown block_size
|
# mount with unknown block_size/block_count
|
||||||
[cases.test_superblocks_unknown_block_size]
|
[cases.test_superblocks_unknowns]
|
||||||
code = '''
|
code = '''
|
||||||
lfs_t lfs;
|
lfs_t lfs;
|
||||||
lfs_format(&lfs, cfg) => 0;
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
|
||||||
cfg->block_size = 0;
|
// known block_size/block_count
|
||||||
|
cfg->block_size = BLOCK_SIZE;
|
||||||
|
cfg->block_count = BLOCK_COUNT;
|
||||||
lfs_mount(&lfs, cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
struct lfs_fsinfo fsinfo;
|
struct lfs_fsinfo fsinfo;
|
||||||
lfs_fs_stat(&lfs, &fsinfo) => 0;
|
lfs_fs_stat(&lfs, &fsinfo) => 0;
|
||||||
assert(fsinfo.block_size == BLOCK_SIZE);
|
assert(fsinfo.block_size == BLOCK_SIZE);
|
||||||
assert(fsinfo.block_count == BLOCK_COUNT);
|
assert(fsinfo.block_count == BLOCK_COUNT);
|
||||||
|
|
||||||
lfs_file_t file;
|
|
||||||
lfs_file_open(&lfs, &file, "test",
|
|
||||||
LFS_O_CREAT | LFS_O_EXCL | LFS_O_WRONLY) => 0;
|
|
||||||
lfs_file_write(&lfs, &file, "hello!", 6) => 6;
|
|
||||||
lfs_file_close(&lfs, &file) => 0;
|
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
lfs_mount(&lfs, cfg) => 0;
|
// unknown block_count
|
||||||
lfs_fs_stat(&lfs, &fsinfo) => 0;
|
cfg->block_size = BLOCK_SIZE;
|
||||||
assert(fsinfo.block_size == BLOCK_SIZE);
|
|
||||||
assert(fsinfo.block_count == BLOCK_COUNT);
|
|
||||||
|
|
||||||
lfs_file_open(&lfs, &file, "test", LFS_O_RDONLY) => 0;
|
|
||||||
uint8_t buffer[256];
|
|
||||||
lfs_file_read(&lfs, &file, buffer, sizeof(buffer)) => 6;
|
|
||||||
lfs_file_close(&lfs, &file) => 0;
|
|
||||||
assert(memcmp(buffer, "hello!", 6) == 0);
|
|
||||||
lfs_unmount(&lfs) => 0;
|
|
||||||
'''
|
|
||||||
|
|
||||||
# mount with unknown block_count
|
|
||||||
[cases.test_superblocks_unknown_block_count]
|
|
||||||
code = '''
|
|
||||||
lfs_t lfs;
|
|
||||||
lfs_format(&lfs, cfg) => 0;
|
|
||||||
|
|
||||||
cfg->block_count = 0;
|
cfg->block_count = 0;
|
||||||
|
|
||||||
lfs_mount(&lfs, cfg) => 0;
|
|
||||||
struct lfs_fsinfo fsinfo;
|
|
||||||
lfs_fs_stat(&lfs, &fsinfo) => 0;
|
|
||||||
assert(fsinfo.block_size == BLOCK_SIZE);
|
|
||||||
assert(fsinfo.block_count == BLOCK_COUNT);
|
|
||||||
|
|
||||||
lfs_file_t file;
|
|
||||||
lfs_file_open(&lfs, &file, "test",
|
|
||||||
LFS_O_CREAT | LFS_O_EXCL | LFS_O_WRONLY) => 0;
|
|
||||||
lfs_file_write(&lfs, &file, "hello!", 6) => 6;
|
|
||||||
lfs_file_close(&lfs, &file) => 0;
|
|
||||||
lfs_unmount(&lfs) => 0;
|
|
||||||
|
|
||||||
lfs_mount(&lfs, cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_fs_stat(&lfs, &fsinfo) => 0;
|
lfs_fs_stat(&lfs, &fsinfo) => 0;
|
||||||
assert(fsinfo.block_size == BLOCK_SIZE);
|
assert(fsinfo.block_size == BLOCK_SIZE);
|
||||||
assert(fsinfo.block_count == BLOCK_COUNT);
|
assert(fsinfo.block_count == BLOCK_COUNT);
|
||||||
|
|
||||||
lfs_file_open(&lfs, &file, "test", LFS_O_RDONLY) => 0;
|
|
||||||
uint8_t buffer[256];
|
|
||||||
lfs_file_read(&lfs, &file, buffer, sizeof(buffer)) => 6;
|
|
||||||
lfs_file_close(&lfs, &file) => 0;
|
|
||||||
assert(memcmp(buffer, "hello!", 6) == 0);
|
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
|
||||||
|
|
||||||
# mount with unknown block_size+block_count
|
// unknown block_size
|
||||||
[cases.test_superblocks_unknown_block_size_count]
|
cfg->block_size = 0;
|
||||||
code = '''
|
cfg->block_count = ERASE_COUNT;
|
||||||
lfs_t lfs;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
lfs_format(&lfs, cfg) => 0;
|
lfs_fs_stat(&lfs, &fsinfo) => 0;
|
||||||
|
assert(fsinfo.block_size == BLOCK_SIZE);
|
||||||
|
assert(fsinfo.block_count == BLOCK_COUNT);
|
||||||
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
|
// unknown block_count/block_size
|
||||||
cfg->block_size = 0;
|
cfg->block_size = 0;
|
||||||
cfg->block_count = 0;
|
cfg->block_count = 0;
|
||||||
|
|
||||||
lfs_mount(&lfs, cfg) => 0;
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
struct lfs_fsinfo fsinfo;
|
|
||||||
lfs_fs_stat(&lfs, &fsinfo) => 0;
|
lfs_fs_stat(&lfs, &fsinfo) => 0;
|
||||||
assert(fsinfo.block_size == BLOCK_SIZE);
|
assert(fsinfo.block_size == BLOCK_SIZE);
|
||||||
assert(fsinfo.block_count == BLOCK_COUNT);
|
assert(fsinfo.block_count == BLOCK_COUNT);
|
||||||
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
|
// do some work
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
lfs_fs_stat(&lfs, &fsinfo) => 0;
|
||||||
|
assert(fsinfo.block_size == BLOCK_SIZE);
|
||||||
|
assert(fsinfo.block_count == BLOCK_COUNT);
|
||||||
lfs_file_t file;
|
lfs_file_t file;
|
||||||
lfs_file_open(&lfs, &file, "test",
|
lfs_file_open(&lfs, &file, "test",
|
||||||
LFS_O_CREAT | LFS_O_EXCL | LFS_O_WRONLY) => 0;
|
LFS_O_CREAT | LFS_O_EXCL | LFS_O_WRONLY) => 0;
|
||||||
@@ -244,7 +209,6 @@ code = '''
|
|||||||
lfs_fs_stat(&lfs, &fsinfo) => 0;
|
lfs_fs_stat(&lfs, &fsinfo) => 0;
|
||||||
assert(fsinfo.block_size == BLOCK_SIZE);
|
assert(fsinfo.block_size == BLOCK_SIZE);
|
||||||
assert(fsinfo.block_count == BLOCK_COUNT);
|
assert(fsinfo.block_count == BLOCK_COUNT);
|
||||||
|
|
||||||
lfs_file_open(&lfs, &file, "test", LFS_O_RDONLY) => 0;
|
lfs_file_open(&lfs, &file, "test", LFS_O_RDONLY) => 0;
|
||||||
uint8_t buffer[256];
|
uint8_t buffer[256];
|
||||||
lfs_file_read(&lfs, &file, buffer, sizeof(buffer)) => 6;
|
lfs_file_read(&lfs, &file, buffer, sizeof(buffer)) => 6;
|
||||||
@@ -252,3 +216,346 @@ code = '''
|
|||||||
assert(memcmp(buffer, "hello!", 6) == 0);
|
assert(memcmp(buffer, "hello!", 6) == 0);
|
||||||
lfs_unmount(&lfs) => 0;
|
lfs_unmount(&lfs) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
# mount with blocks larger than the erase_size
|
||||||
|
[cases.test_superblocks_larger_blocks]
|
||||||
|
defines.BLOCK_SIZE = [
|
||||||
|
'2*ERASE_SIZE',
|
||||||
|
'4*ERASE_SIZE',
|
||||||
|
'(ERASE_COUNT/2)*ERASE_SIZE']
|
||||||
|
code = '''
|
||||||
|
lfs_t lfs;
|
||||||
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
|
||||||
|
// known block_size/block_count
|
||||||
|
cfg->block_size = BLOCK_SIZE;
|
||||||
|
cfg->block_count = BLOCK_COUNT;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
struct lfs_fsinfo fsinfo;
|
||||||
|
lfs_fs_stat(&lfs, &fsinfo) => 0;
|
||||||
|
assert(fsinfo.block_size == BLOCK_SIZE);
|
||||||
|
assert(fsinfo.block_count == BLOCK_COUNT);
|
||||||
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
|
// incorrect block_size
|
||||||
|
cfg->block_size = ERASE_SIZE;
|
||||||
|
cfg->block_count = 0;
|
||||||
|
lfs_mount(&lfs, cfg) => LFS_ERR_INVAL;
|
||||||
|
|
||||||
|
// unknown block_count
|
||||||
|
cfg->block_size = BLOCK_SIZE;
|
||||||
|
cfg->block_count = 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
lfs_fs_stat(&lfs, &fsinfo) => 0;
|
||||||
|
assert(fsinfo.block_size == BLOCK_SIZE);
|
||||||
|
assert(fsinfo.block_count == BLOCK_COUNT);
|
||||||
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
|
// unknown block_size
|
||||||
|
cfg->block_size = 0;
|
||||||
|
cfg->block_count = ERASE_COUNT;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
lfs_fs_stat(&lfs, &fsinfo) => 0;
|
||||||
|
assert(fsinfo.block_size == BLOCK_SIZE);
|
||||||
|
assert(fsinfo.block_count == BLOCK_COUNT);
|
||||||
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
|
// unknown block_count/block_size
|
||||||
|
cfg->block_size = 0;
|
||||||
|
cfg->block_count = 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
lfs_fs_stat(&lfs, &fsinfo) => 0;
|
||||||
|
assert(fsinfo.block_size == BLOCK_SIZE);
|
||||||
|
assert(fsinfo.block_count == BLOCK_COUNT);
|
||||||
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
|
// do some work
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
lfs_fs_stat(&lfs, &fsinfo) => 0;
|
||||||
|
assert(fsinfo.block_size == BLOCK_SIZE);
|
||||||
|
assert(fsinfo.block_count == BLOCK_COUNT);
|
||||||
|
lfs_file_t file;
|
||||||
|
lfs_file_open(&lfs, &file, "test",
|
||||||
|
LFS_O_CREAT | LFS_O_EXCL | LFS_O_WRONLY) => 0;
|
||||||
|
lfs_file_write(&lfs, &file, "hello!", 6) => 6;
|
||||||
|
lfs_file_close(&lfs, &file) => 0;
|
||||||
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
lfs_fs_stat(&lfs, &fsinfo) => 0;
|
||||||
|
assert(fsinfo.block_size == BLOCK_SIZE);
|
||||||
|
assert(fsinfo.block_count == BLOCK_COUNT);
|
||||||
|
lfs_file_open(&lfs, &file, "test", LFS_O_RDONLY) => 0;
|
||||||
|
uint8_t buffer[256];
|
||||||
|
lfs_file_read(&lfs, &file, buffer, sizeof(buffer)) => 6;
|
||||||
|
lfs_file_close(&lfs, &file) => 0;
|
||||||
|
assert(memcmp(buffer, "hello!", 6) == 0);
|
||||||
|
lfs_unmount(&lfs) => 0;
|
||||||
|
'''
|
||||||
|
|
||||||
|
# mount with blocks smaller than the erase_size
|
||||||
|
[cases.test_superblocks_smaller_blocks]
|
||||||
|
defines.FORMAT_BLOCK_SIZE = 'ERASE_SIZE/2'
|
||||||
|
defines.FORMAT_BLOCK_COUNT = 'BLOCK_COUNT * (BLOCK_SIZE/FORMAT_BLOCK_SIZE)'
|
||||||
|
in = 'lfs.c'
|
||||||
|
code = '''
|
||||||
|
lfs_t lfs;
|
||||||
|
lfs_init(&lfs, cfg) => 0;
|
||||||
|
lfs.block_size = BLOCK_SIZE;
|
||||||
|
lfs.block_count = BLOCK_COUNT;
|
||||||
|
|
||||||
|
lfs_mdir_t root = {
|
||||||
|
.pair = {0, 0}, // make sure this goes into block 0
|
||||||
|
.rev = 0,
|
||||||
|
.off = sizeof(uint32_t),
|
||||||
|
.etag = 0xffffffff,
|
||||||
|
.count = 0,
|
||||||
|
.tail = {LFS_BLOCK_NULL, LFS_BLOCK_NULL},
|
||||||
|
.erased = false,
|
||||||
|
.split = false,
|
||||||
|
};
|
||||||
|
|
||||||
|
lfs_superblock_t superblock = {
|
||||||
|
.version = LFS_DISK_VERSION,
|
||||||
|
.block_size = FORMAT_BLOCK_SIZE,
|
||||||
|
.block_count = FORMAT_BLOCK_COUNT,
|
||||||
|
.name_max = LFS_NAME_MAX,
|
||||||
|
.file_max = LFS_FILE_MAX,
|
||||||
|
.attr_max = LFS_ATTR_MAX,
|
||||||
|
};
|
||||||
|
|
||||||
|
lfs_superblock_tole32(&superblock);
|
||||||
|
lfs_dir_commit(&lfs, &root, LFS_MKATTRS(
|
||||||
|
{LFS_MKTAG(LFS_TYPE_CREATE, 0, 0), NULL},
|
||||||
|
{LFS_MKTAG(LFS_TYPE_SUPERBLOCK, 0, 8), "littlefs"},
|
||||||
|
{LFS_MKTAG(LFS_TYPE_INLINESTRUCT, 0, sizeof(superblock)),
|
||||||
|
&superblock})) => 0;
|
||||||
|
|
||||||
|
// known block_size/block_count
|
||||||
|
cfg->block_size = BLOCK_SIZE;
|
||||||
|
cfg->block_count = BLOCK_COUNT;
|
||||||
|
lfs_mount(&lfs, cfg) => LFS_ERR_INVAL;
|
||||||
|
|
||||||
|
// unknown block_count
|
||||||
|
cfg->block_size = BLOCK_SIZE;
|
||||||
|
cfg->block_count = 0;
|
||||||
|
lfs_mount(&lfs, cfg) => LFS_ERR_INVAL;
|
||||||
|
|
||||||
|
// unknown block_size
|
||||||
|
cfg->block_size = 0;
|
||||||
|
cfg->block_count = ERASE_COUNT;
|
||||||
|
lfs_mount(&lfs, cfg) => LFS_ERR_INVAL;
|
||||||
|
|
||||||
|
// unknown block_count/block_size
|
||||||
|
cfg->block_size = 0;
|
||||||
|
cfg->block_count = 0;
|
||||||
|
lfs_mount(&lfs, cfg) => LFS_ERR_INVAL;
|
||||||
|
'''
|
||||||
|
|
||||||
|
# mount with blocks fewer than the erase_count
|
||||||
|
[cases.test_superblocks_fewer_blocks]
|
||||||
|
defines.BLOCK_COUNT = ['ERASE_COUNT/2', 'ERASE_COUNT/4', '2']
|
||||||
|
code = '''
|
||||||
|
lfs_t lfs;
|
||||||
|
lfs_format(&lfs, cfg) => 0;
|
||||||
|
|
||||||
|
// known block_size/block_count
|
||||||
|
cfg->block_size = BLOCK_SIZE;
|
||||||
|
cfg->block_count = BLOCK_COUNT;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
struct lfs_fsinfo fsinfo;
|
||||||
|
lfs_fs_stat(&lfs, &fsinfo) => 0;
|
||||||
|
assert(fsinfo.block_size == BLOCK_SIZE);
|
||||||
|
assert(fsinfo.block_count == BLOCK_COUNT);
|
||||||
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
|
// incorrect block_count
|
||||||
|
cfg->block_size = BLOCK_SIZE;
|
||||||
|
cfg->block_count = ERASE_COUNT;
|
||||||
|
lfs_mount(&lfs, cfg) => LFS_ERR_INVAL;
|
||||||
|
|
||||||
|
// unknown block_count
|
||||||
|
cfg->block_size = BLOCK_SIZE;
|
||||||
|
cfg->block_count = 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
lfs_fs_stat(&lfs, &fsinfo) => 0;
|
||||||
|
assert(fsinfo.block_size == BLOCK_SIZE);
|
||||||
|
assert(fsinfo.block_count == BLOCK_COUNT);
|
||||||
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
|
// unknown block_size
|
||||||
|
cfg->block_size = 0;
|
||||||
|
cfg->block_count = BLOCK_COUNT;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
lfs_fs_stat(&lfs, &fsinfo) => 0;
|
||||||
|
assert(fsinfo.block_size == BLOCK_SIZE);
|
||||||
|
assert(fsinfo.block_count == BLOCK_COUNT);
|
||||||
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
|
// unknown block_count/block_size
|
||||||
|
cfg->block_size = 0;
|
||||||
|
cfg->block_count = 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
lfs_fs_stat(&lfs, &fsinfo) => 0;
|
||||||
|
assert(fsinfo.block_size == BLOCK_SIZE);
|
||||||
|
assert(fsinfo.block_count == BLOCK_COUNT);
|
||||||
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
|
// do some work
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
lfs_fs_stat(&lfs, &fsinfo) => 0;
|
||||||
|
assert(fsinfo.block_size == BLOCK_SIZE);
|
||||||
|
assert(fsinfo.block_count == BLOCK_COUNT);
|
||||||
|
lfs_file_t file;
|
||||||
|
lfs_file_open(&lfs, &file, "test",
|
||||||
|
LFS_O_CREAT | LFS_O_EXCL | LFS_O_WRONLY) => 0;
|
||||||
|
lfs_file_write(&lfs, &file, "hello!", 6) => 6;
|
||||||
|
lfs_file_close(&lfs, &file) => 0;
|
||||||
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
lfs_fs_stat(&lfs, &fsinfo) => 0;
|
||||||
|
assert(fsinfo.block_size == BLOCK_SIZE);
|
||||||
|
assert(fsinfo.block_count == BLOCK_COUNT);
|
||||||
|
lfs_file_open(&lfs, &file, "test", LFS_O_RDONLY) => 0;
|
||||||
|
uint8_t buffer[256];
|
||||||
|
lfs_file_read(&lfs, &file, buffer, sizeof(buffer)) => 6;
|
||||||
|
lfs_file_close(&lfs, &file) => 0;
|
||||||
|
assert(memcmp(buffer, "hello!", 6) == 0);
|
||||||
|
lfs_unmount(&lfs) => 0;
|
||||||
|
'''
|
||||||
|
|
||||||
|
# mount with more blocks than the erase_count
|
||||||
|
[cases.test_superblocks_more_blocks]
|
||||||
|
defines.FORMAT_BLOCK_COUNT = '2*ERASE_COUNT'
|
||||||
|
in = 'lfs.c'
|
||||||
|
code = '''
|
||||||
|
lfs_t lfs;
|
||||||
|
lfs_init(&lfs, cfg) => 0;
|
||||||
|
lfs.block_size = BLOCK_SIZE;
|
||||||
|
lfs.block_count = BLOCK_COUNT;
|
||||||
|
|
||||||
|
lfs_mdir_t root = {
|
||||||
|
.pair = {0, 0}, // make sure this goes into block 0
|
||||||
|
.rev = 0,
|
||||||
|
.off = sizeof(uint32_t),
|
||||||
|
.etag = 0xffffffff,
|
||||||
|
.count = 0,
|
||||||
|
.tail = {LFS_BLOCK_NULL, LFS_BLOCK_NULL},
|
||||||
|
.erased = false,
|
||||||
|
.split = false,
|
||||||
|
};
|
||||||
|
|
||||||
|
lfs_superblock_t superblock = {
|
||||||
|
.version = LFS_DISK_VERSION,
|
||||||
|
.block_size = BLOCK_SIZE,
|
||||||
|
.block_count = FORMAT_BLOCK_COUNT,
|
||||||
|
.name_max = LFS_NAME_MAX,
|
||||||
|
.file_max = LFS_FILE_MAX,
|
||||||
|
.attr_max = LFS_ATTR_MAX,
|
||||||
|
};
|
||||||
|
|
||||||
|
lfs_superblock_tole32(&superblock);
|
||||||
|
lfs_dir_commit(&lfs, &root, LFS_MKATTRS(
|
||||||
|
{LFS_MKTAG(LFS_TYPE_CREATE, 0, 0), NULL},
|
||||||
|
{LFS_MKTAG(LFS_TYPE_SUPERBLOCK, 0, 8), "littlefs"},
|
||||||
|
{LFS_MKTAG(LFS_TYPE_INLINESTRUCT, 0, sizeof(superblock)),
|
||||||
|
&superblock})) => 0;
|
||||||
|
|
||||||
|
// known block_size/block_count
|
||||||
|
cfg->block_size = BLOCK_SIZE;
|
||||||
|
cfg->block_count = BLOCK_COUNT;
|
||||||
|
lfs_mount(&lfs, cfg) => LFS_ERR_INVAL;
|
||||||
|
|
||||||
|
// unknown block_size
|
||||||
|
cfg->block_size = 0;
|
||||||
|
cfg->block_count = ERASE_COUNT;
|
||||||
|
lfs_mount(&lfs, cfg) => LFS_ERR_INVAL;
|
||||||
|
'''
|
||||||
|
|
||||||
|
# the real challenge is finding superblock 1 when block_size is unknown,
|
||||||
|
# test for this explicitly
|
||||||
|
[cases.test_superblocks_unknown_superblock1]
|
||||||
|
in = 'lfs.c'
|
||||||
|
defines.BLOCK_SIZE = [
|
||||||
|
'ERASE_SIZE',
|
||||||
|
'2*ERASE_SIZE',
|
||||||
|
'4*ERASE_SIZE',
|
||||||
|
'(ERASE_COUNT/2)*ERASE_SIZE']
|
||||||
|
code = '''
|
||||||
|
lfs_t lfs;
|
||||||
|
lfs_init(&lfs, cfg) => 0;
|
||||||
|
lfs.block_size = BLOCK_SIZE;
|
||||||
|
lfs.block_count = BLOCK_COUNT;
|
||||||
|
|
||||||
|
uint8_t buffer[lfs_max(READ_SIZE, sizeof(uint32_t))];
|
||||||
|
memset(buffer, 0, lfs_max(READ_SIZE, sizeof(uint32_t)));
|
||||||
|
cfg->read(cfg, 0, 0, buffer, lfs_max(READ_SIZE, sizeof(uint32_t))) => 0;
|
||||||
|
uint32_t rev;
|
||||||
|
memcpy(&rev, buffer, sizeof(uint32_t));
|
||||||
|
rev = lfs_fromle32(rev);
|
||||||
|
|
||||||
|
lfs_mdir_t root = {
|
||||||
|
.pair = {1, 1}, // make sure this goes into block 1
|
||||||
|
.rev = rev,
|
||||||
|
.off = sizeof(uint32_t),
|
||||||
|
.etag = 0xffffffff,
|
||||||
|
.count = 0,
|
||||||
|
.tail = {LFS_BLOCK_NULL, LFS_BLOCK_NULL},
|
||||||
|
.erased = false,
|
||||||
|
.split = false,
|
||||||
|
};
|
||||||
|
|
||||||
|
lfs_superblock_t superblock = {
|
||||||
|
.version = LFS_DISK_VERSION,
|
||||||
|
.block_size = BLOCK_SIZE,
|
||||||
|
.block_count = BLOCK_COUNT,
|
||||||
|
.name_max = LFS_NAME_MAX,
|
||||||
|
.file_max = LFS_FILE_MAX,
|
||||||
|
.attr_max = LFS_ATTR_MAX,
|
||||||
|
};
|
||||||
|
|
||||||
|
lfs_superblock_tole32(&superblock);
|
||||||
|
lfs_dir_commit(&lfs, &root, LFS_MKATTRS(
|
||||||
|
{LFS_MKTAG(LFS_TYPE_CREATE, 0, 0), NULL},
|
||||||
|
{LFS_MKTAG(LFS_TYPE_SUPERBLOCK, 0, 8), "littlefs"},
|
||||||
|
{LFS_MKTAG(LFS_TYPE_INLINESTRUCT, 0, sizeof(superblock)),
|
||||||
|
&superblock})) => 0;
|
||||||
|
|
||||||
|
// known block_size/block_count
|
||||||
|
cfg->block_size = BLOCK_SIZE;
|
||||||
|
cfg->block_count = BLOCK_COUNT;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
struct lfs_fsinfo fsinfo;
|
||||||
|
lfs_fs_stat(&lfs, &fsinfo) => 0;
|
||||||
|
assert(fsinfo.block_size == BLOCK_SIZE);
|
||||||
|
assert(fsinfo.block_count == BLOCK_COUNT);
|
||||||
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
|
// unknown block_count
|
||||||
|
cfg->block_size = BLOCK_SIZE;
|
||||||
|
cfg->block_count = 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
lfs_fs_stat(&lfs, &fsinfo) => 0;
|
||||||
|
assert(fsinfo.block_size == BLOCK_SIZE);
|
||||||
|
assert(fsinfo.block_count == BLOCK_COUNT);
|
||||||
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
|
// unknown block_size
|
||||||
|
cfg->block_size = 0;
|
||||||
|
cfg->block_count = ERASE_COUNT;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
lfs_fs_stat(&lfs, &fsinfo) => 0;
|
||||||
|
assert(fsinfo.block_size == BLOCK_SIZE);
|
||||||
|
assert(fsinfo.block_count == BLOCK_COUNT);
|
||||||
|
lfs_unmount(&lfs) => 0;
|
||||||
|
|
||||||
|
// unknown block_count/block_size
|
||||||
|
cfg->block_size = 0;
|
||||||
|
cfg->block_count = 0;
|
||||||
|
lfs_mount(&lfs, cfg) => 0;
|
||||||
|
lfs_fs_stat(&lfs, &fsinfo) => 0;
|
||||||
|
assert(fsinfo.block_size == BLOCK_SIZE);
|
||||||
|
assert(fsinfo.block_count == BLOCK_COUNT);
|
||||||
|
lfs_unmount(&lfs) => 0;
|
||||||
|
'''
|
||||||
|
|||||||
Reference in New Issue
Block a user