diff options
Diffstat (limited to 'lib/littlefs/lfs2.c')
-rw-r--r-- | lib/littlefs/lfs2.c | 80 |
1 files changed, 54 insertions, 26 deletions
diff --git a/lib/littlefs/lfs2.c b/lib/littlefs/lfs2.c index f9ce2cf290..abdec19d7c 100644 --- a/lib/littlefs/lfs2.c +++ b/lib/littlefs/lfs2.c @@ -3932,7 +3932,9 @@ static int lfs2_remove_(lfs2_t *lfs2, const char *path) { } lfs2->mlist = dir.next; - if (lfs2_tag_type3(tag) == LFS2_TYPE_DIR) { + if (lfs2_gstate_hasorphans(&lfs2->gstate)) { + LFS2_ASSERT(lfs2_tag_type3(tag) == LFS2_TYPE_DIR); + // fix orphan err = lfs2_fs_preporphans(lfs2, -1); if (err) { @@ -4076,8 +4078,10 @@ static int lfs2_rename_(lfs2_t *lfs2, const char *oldpath, const char *newpath) } lfs2->mlist = prevdir.next; - if (prevtag != LFS2_ERR_NOENT - && lfs2_tag_type3(prevtag) == LFS2_TYPE_DIR) { + if (lfs2_gstate_hasorphans(&lfs2->gstate)) { + LFS2_ASSERT(prevtag != LFS2_ERR_NOENT + && lfs2_tag_type3(prevtag) == LFS2_TYPE_DIR); + // fix orphan err = lfs2_fs_preporphans(lfs2, -1); if (err) { @@ -5233,40 +5237,64 @@ static int lfs2_fs_gc_(lfs2_t *lfs2) { #endif #ifndef LFS2_READONLY +#ifdef LFS2_SHRINKNONRELOCATING +static int lfs2_shrink_checkblock(void *data, lfs2_block_t block) { + lfs2_size_t threshold = *((lfs2_size_t*)data); + if (block >= threshold) { + return LFS2_ERR_NOTEMPTY; + } + return 0; +} +#endif + static int lfs2_fs_grow_(lfs2_t *lfs2, lfs2_size_t block_count) { - // shrinking is not supported - LFS2_ASSERT(block_count >= lfs2->block_count); + int err; - if (block_count > lfs2->block_count) { - lfs2->block_count = block_count; + if (block_count == lfs2->block_count) { + return 0; + } - // fetch the root - lfs2_mdir_t root; - int err = lfs2_dir_fetch(lfs2, &root, lfs2->root); + +#ifndef LFS2_SHRINKNONRELOCATING + // shrinking is not supported + LFS2_ASSERT(block_count >= lfs2->block_count); +#endif +#ifdef LFS2_SHRINKNONRELOCATING + if (block_count < lfs2->block_count) { + err = lfs2_fs_traverse_(lfs2, lfs2_shrink_checkblock, &block_count, true); if (err) { return err; } + } +#endif - // update the superblock - lfs2_superblock_t superblock; - lfs2_stag_t tag = lfs2_dir_get(lfs2, &root, LFS2_MKTAG(0x7ff, 0x3ff, 0), - LFS2_MKTAG(LFS2_TYPE_INLINESTRUCT, 0, sizeof(superblock)), - &superblock); - if (tag < 0) { - return tag; - } - lfs2_superblock_fromle32(&superblock); + lfs2->block_count = block_count; - superblock.block_count = lfs2->block_count; + // fetch the root + lfs2_mdir_t root; + err = lfs2_dir_fetch(lfs2, &root, lfs2->root); + if (err) { + return err; + } - lfs2_superblock_tole32(&superblock); - err = lfs2_dir_commit(lfs2, &root, LFS2_MKATTRS( - {tag, &superblock})); - if (err) { - return err; - } + // update the superblock + lfs2_superblock_t superblock; + lfs2_stag_t tag = lfs2_dir_get(lfs2, &root, LFS2_MKTAG(0x7ff, 0x3ff, 0), + LFS2_MKTAG(LFS2_TYPE_INLINESTRUCT, 0, sizeof(superblock)), + &superblock); + if (tag < 0) { + return tag; } + lfs2_superblock_fromle32(&superblock); + + superblock.block_count = lfs2->block_count; + lfs2_superblock_tole32(&superblock); + err = lfs2_dir_commit(lfs2, &root, LFS2_MKATTRS( + {tag, &superblock})); + if (err) { + return err; + } return 0; } #endif |