diff --git a/lfs.c b/lfs.c index 563df64c..88ef79c3 100644 --- a/lfs.c +++ b/lfs.c @@ -13373,21 +13373,6 @@ int lfsr_mount(lfs_t *lfs, uint32_t flags, goto failed; } - // TODO this should use any configured values - LFS_DEBUG("Mounted littlefs v%"PRId32".%"PRId32" " - "%"PRId32"x%"PRId32" " - "0x{%"PRIx32",%"PRIx32"}.%"PRIx32" " - "w%"PRId32".%"PRId32, - LFS_DISK_VERSION_MAJOR, - LFS_DISK_VERSION_MINOR, - lfs->cfg->block_size, - lfs->block_count, - lfs->mroot.rbyd.blocks[0], - lfs->mroot.rbyd.blocks[1], - lfsr_rbyd_trunk(&lfs->mroot.rbyd), - lfsr_mtree_weight_(&lfs->mtree) >> lfs->mdir_bits, - 1 << lfs->mdir_bits); - // run gc if requested if (flags & ( LFS_M_MTREEONLY @@ -13409,6 +13394,21 @@ int lfsr_mount(lfs_t *lfs, uint32_t flags, } } + // TODO this should use any configured values + LFS_DEBUG("Mounted littlefs v%"PRId32".%"PRId32" " + "%"PRId32"x%"PRId32" " + "0x{%"PRIx32",%"PRIx32"}.%"PRIx32" " + "w%"PRId32".%"PRId32, + LFS_DISK_VERSION_MAJOR, + LFS_DISK_VERSION_MINOR, + lfs->cfg->block_size, + lfs->block_count, + lfs->mroot.rbyd.blocks[0], + lfs->mroot.rbyd.blocks[1], + lfsr_rbyd_trunk(&lfs->mroot.rbyd), + lfsr_mtree_weight_(&lfs->mtree) >> lfs->mdir_bits, + 1 << lfs->mdir_bits); + return 0; failed:; @@ -13493,12 +13493,6 @@ static int lfsr_formatinited(lfs_t *lfs) { return err; } - // test that mount works with our formatted disk - err = lfsr_mountinited(lfs); - if (err) { - return err; - } - return 0; } @@ -13508,7 +13502,11 @@ int lfsr_format(lfs_t *lfs, uint32_t flags, LFS_ASSERT((flags & ~( LFS_F_RDWR | LFS_F_CKPROGS - | LFS_IFDEF_CKREADS(LFS_F_CKREADS, 0))) == 0); + | LFS_IFDEF_CKREADS(LFS_F_CKREADS, 0) + | LFS_F_MTREEONLY + | LFS_F_COMPACT + | LFS_F_CKMETA + | LFS_F_CKDATA)) == 0); // some flags don't make sense when only traversing the mtree LFS_ASSERT(!lfsr_t_ismtreeonly(flags) || !lfsr_t_isckdata(flags)); @@ -13526,12 +13524,38 @@ int lfsr_format(lfs_t *lfs, uint32_t flags, err = lfsr_formatinited(lfs); if (err) { - // make sure we clean up on error - lfs_deinit(lfs); - return err; + goto failed; + } + + // test that mount works with our formatted disk + err = lfsr_mountinited(lfs); + if (err) { + goto failed; + } + + // run gc if requested + if (flags & ( + LFS_F_MTREEONLY + | LFS_F_COMPACT + | LFS_F_CKMETA + | LFS_F_CKDATA)) { + err = lfsr_fs_gc(lfs, -1, + flags & ( + LFS_F_MTREEONLY + | LFS_F_COMPACT + | LFS_F_CKMETA + | LFS_F_CKDATA)); + if (err) { + goto failed; + } } return lfs_deinit(lfs); + +failed:; + // make sure we clean up on error + lfs_deinit(lfs); + return err; } diff --git a/lfs.h b/lfs.h index 61984451..f396edca 100644 --- a/lfs.h +++ b/lfs.h @@ -158,6 +158,11 @@ enum lfs_type { #define LFS_F_CKREADS 0x00000020 // Check reads via parity bits/checksums #endif +#define LFS_F_MTREEONLY 0x00010000 // Only traverse the mtree +#define LFS_F_COMPACT 0x00000800 // Compact metadata logs +#define LFS_F_CKMETA 0x00001000 // Check metadata checksums +#define LFS_F_CKDATA 0x00002000 // Check metadata + data checksums + // Filesystem mount flags #define LFS_M_RDWR 0 // Mount the filesystem as read and write #define LFS_M_RDONLY 1 // Mount the filesystem as read only diff --git a/tests/test_mount.toml b/tests/test_mount.toml index e9698b1c..deea68eb 100644 --- a/tests/test_mount.toml +++ b/tests/test_mount.toml @@ -11,14 +11,28 @@ code = ''' lfsr_unmount(&lfs) => 0; ''' -# test that various mount flags are returned by lfsr_fs_stat +# test that various mount flags don't assert and are returned by +# lfsr_fs_stat [cases.test_mount_flags] defines.RDONLY = [false, true] defines.CKPROGS = [false, true] defines.CKREADS = [false, true] defines.FLUSH = [false, true] defines.SYNC = [false, true] -if = 'LFS_IFDEF_CKREADS(true, !CKREADS)' +defines.MTREEONLY = [false, true] +defines.MKCONSISTENT = [false, true] +defines.LOOKAHEAD = [false, true] +defines.COMPACT = [false, true] +defines.CKMETA = [false, true] +defines.CKDATA = [false, true] +if = [ + 'LFS_IFDEF_CKREADS(true, !CKREADS)', + '!RDONLY || !MKCONSISTENT', + '!RDONLY || !LOOKAHEAD', + '!RDONLY || !COMPACT', + '!MTREEONLY || !LOOKAHEAD', + '!MTREEONLY || !CKDATA', +] code = ''' lfs_t lfs; lfsr_format(&lfs, LFS_F_RDWR, CFG) => 0; @@ -27,9 +41,16 @@ code = ''' | ((CKPROGS) ? LFS_M_CKPROGS : 0) | ((CKREADS) ? LFS_IFDEF_CKREADS(LFS_M_CKREADS, 0) : 0) | ((FLUSH) ? LFS_M_FLUSH : 0) - | ((SYNC) ? LFS_M_SYNC : 0), + | ((SYNC) ? LFS_M_SYNC : 0) + | ((MTREEONLY) ? LFS_M_MTREEONLY : 0) + | ((MKCONSISTENT) ? LFS_M_MKCONSISTENT : 0) + | ((LOOKAHEAD) ? LFS_M_LOOKAHEAD : 0) + | ((COMPACT) ? LFS_M_COMPACT : 0) + | ((CKMETA) ? LFS_M_CKMETA : 0) + | ((CKDATA) ? LFS_M_CKDATA : 0), CFG) => 0; + // lfsr_fs_stat only returns some flags struct lfs_fsinfo fsinfo; lfsr_fs_stat(&lfs, &fsinfo) => 0; assert(fsinfo.flags == ( @@ -38,8 +59,8 @@ code = ''' | ((CKREADS) ? LFS_IFDEF_CKREADS(LFS_I_CKREADS, 0) : 0) | ((FLUSH) ? LFS_I_FLUSH : 0) | ((SYNC) ? LFS_I_SYNC : 0) - | LFS_I_CANLOOKAHEAD - | LFS_I_UNCOMPACTED)); + | ((!LOOKAHEAD) ? LFS_I_CANLOOKAHEAD : 0) + | ((!COMPACT) ? LFS_I_UNCOMPACTED : 0))); lfsr_unmount(&lfs) => 0; ''' @@ -50,13 +71,24 @@ code = ''' [cases.test_mount_format_flags] defines.CKPROGS = [false, true] defines.CKREADS = [false, true] -if = 'LFS_IFDEF_CKREADS(true, !CKREADS)' +defines.MTREEONLY = [false, true] +defines.COMPACT = [false, true] +defines.CKMETA = [false, true] +defines.CKDATA = [false, true] +if = [ + 'LFS_IFDEF_CKREADS(true, !CKREADS)', + '!MTREEONLY || !CKDATA', +] code = ''' lfs_t lfs; lfsr_format(&lfs, LFS_F_RDWR | ((CKPROGS) ? LFS_F_CKPROGS : 0) - | ((CKREADS) ? LFS_IFDEF_CKREADS(LFS_F_CKREADS, 0) : 0), + | ((CKREADS) ? LFS_IFDEF_CKREADS(LFS_F_CKREADS, 0) : 0) + | ((MTREEONLY) ? LFS_M_MTREEONLY : 0) + | ((COMPACT) ? LFS_M_COMPACT : 0) + | ((CKMETA) ? LFS_M_CKMETA : 0) + | ((CKDATA) ? LFS_M_CKDATA : 0), CFG) => 0; lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0;