Skip to content

Commit

Permalink
Fixed issue with splitting metadata-pairs in full filesystem
Browse files Browse the repository at this point in the history
Depending on your perspective, this may not be a necessary operation,
given that a nearly-full filesystem is already prone to ENOSPC errors,
especially a COW filesystem. However, splitting metadata-pairs can
happen in really unfortunate situations, such as removing files.

The solution here is to allow "overcompaction", that is, a compaction
without bounds checking to allow splitting. This unfortunately pushes
our metadata-pairs past their reasonable limit of saturation, which
means writes get exponentially costly. However it does allow littlefs to
continue working in extreme situations.
  • Loading branch information
geky committed Oct 18, 2018
1 parent 29b8810 commit cafe6ab
Showing 1 changed file with 14 additions and 5 deletions.
19 changes: 14 additions & 5 deletions lfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand All @@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}

Expand Down

0 comments on commit cafe6ab

Please sign in to comment.