Skip to content

Commit

Permalink
Fixed metadata_max==prog_size commit->end calculation
Browse files Browse the repository at this point in the history
The inconsistency here between the use of block_size vs metadata_max was
suspicious. Turns out there's a but when metadata_max == prog_size.

We correctly use metadata_max for the block_size/2 check, but we weren't
using it for the block_size-40 check. The second check seems unnecessary
after the first, but it protects against running out of space in a
commit for commit-related metadata (checksums, tail pointers, etc) when
we can't program half-blocks.

Turns out this is also needed when limiting metadata_max to a single
prog, otherwise we risk erroring with LFS_ERR_NOSPC early.

Found by ajheck, dpkristensen, and likely others.
  • Loading branch information
geky committed Oct 4, 2024
1 parent 1f82c0f commit 5251c4e
Showing 1 changed file with 5 additions and 4 deletions.
9 changes: 5 additions & 4 deletions lfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -2128,13 +2128,14 @@ static int lfs_dir_splittingcompact(lfs_t *lfs, lfs_mdir_t *dir,
// And we cap at half a block to avoid degenerate cases with
// nearly-full metadata blocks.
//
lfs_size_t metadata_max = (lfs->cfg->metadata_max)
? lfs->cfg->metadata_max
: lfs->cfg->block_size;
if (end - split < 0xff
&& size <= lfs_min(
lfs->cfg->block_size - 40,
metadata_max - 40,
lfs_alignup(
(lfs->cfg->metadata_max
? lfs->cfg->metadata_max
: lfs->cfg->block_size)/2,
metadata_max/2,
lfs->cfg->prog_size))) {
break;
}
Expand Down

0 comments on commit 5251c4e

Please sign in to comment.