forked from Imagelibrary/littlefs
Fixed metadata_max==prog_size commit->end calculation
The inconsistency here between the use of block_size vs metadata_max was suspicious. Turns out there's a bug 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, NLLK, and likely others.
This commit is contained in:
9
lfs.c
9
lfs.c
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user