diff --git a/lfs.c b/lfs.c index 860794649d8..f7cb7972a9f 100644 --- a/lfs.c +++ b/lfs.c @@ -1290,6 +1290,7 @@ static int lfs_dir_compact(lfs_t *lfs, // setup compaction bool splitted = false; bool exhausted = false; + bool overcompacting = false; struct lfs_commit commit; commit.block = dir->pair[1]; @@ -1310,9 +1311,11 @@ static int lfs_dir_compact(lfs_t *lfs, // cleanup delete, and we cap at half a block to give room // for metadata updates commit.begin = 0; - commit.end = lfs_min( - lfs_alignup(lfs->cfg->block_size/2, lfs->cfg->prog_size), - lfs->cfg->block_size - 38); + commit.end = lfs->cfg->block_size - 38; + if (!overcompacting) { + commit.end = lfs_min(commit.end, + lfs_alignup(lfs->cfg->block_size/2, lfs->cfg->prog_size)); + } if (!splitted) { // increment revision count @@ -1369,8 +1372,9 @@ static int lfs_dir_compact(lfs_t *lfs, 0x003ff000, LFS_MKTAG(0, id, 0), -LFS_MKTAG(0, begin, 0), source, attrs); - if (err && !(splitted && err == LFS_ERR_NOSPC)) { - if (err == LFS_ERR_NOSPC) { + if (err && !(splitted && !overcompacting && + err == LFS_ERR_NOSPC)) { + if (!overcompacting && err == LFS_ERR_NOSPC) { goto split; } else if (err == LFS_ERR_CORRUPT) { goto relocate; @@ -1457,6 +1461,11 @@ static int lfs_dir_compact(lfs_t *lfs, lfs_mdir_t tail; err = lfs_dir_alloc(lfs, &tail); if (err) { + if (err == LFS_ERR_NOSPC) { + // No space to expand? Try overcompacting + overcompacting = true; + goto commit; + } return err; }