Prevented attempts to append to block when crystal < prog_size
This will always fail due to prog alignment, but we won't notice because the align flag gets set in the flush loop. So it's not a _hard_ error, but results in an unnecessary btree commit and a bunch of extra reading. Some of these checks aren't necessary if crystal_thresh >= prog_size, which should always be the case, but wanting crystal_size=0 to be a shorthand for "no crystallization" makes it's possible. Maybe we should set crystal_thresh = lfs_max32(crystal_thresh, prog_size) in the future...
This commit is contained in:
@@ -9888,12 +9888,18 @@ static int lfsr_ftree_flush(lfs_t *lfs,
|
|||||||
// wait, found block-level erased-state?
|
// wait, found block-level erased-state?
|
||||||
if (tag == LFSR_TAG_BLOCK
|
if (tag == LFSR_TAG_BLOCK
|
||||||
&& becksum.size != -1
|
&& becksum.size != -1
|
||||||
|
// data not truncated?
|
||||||
&& bptr.data.u.disk.off + lfsr_data_size(&bptr.data)
|
&& bptr.data.u.disk.off + lfsr_data_size(&bptr.data)
|
||||||
== bptr.cksize
|
== bptr.cksize
|
||||||
&& pos - (bid-(weight-1))
|
// not clobbering data?
|
||||||
>= lfsr_data_size(&bptr.data)) {
|
&& crystal_start - (bid-(weight-1))
|
||||||
|
>= lfsr_data_size(&bptr.data)
|
||||||
|
// enough for prog alignment?
|
||||||
|
&& crystal_end - crystal_start
|
||||||
|
>= lfs->cfg->prog_size) {
|
||||||
LFS_ASSERT(bptr.cksize + becksum.size
|
LFS_ASSERT(bptr.cksize + becksum.size
|
||||||
<= lfs->cfg->block_size);
|
<= lfs->cfg->block_size);
|
||||||
|
|
||||||
err = lfsr_ecksum_validate(lfs, &becksum,
|
err = lfsr_ecksum_validate(lfs, &becksum,
|
||||||
bptr.data.u.disk.block, bptr.cksize);
|
bptr.data.u.disk.block, bptr.cksize);
|
||||||
if (err && err != LFS_ERR_CORRUPT) {
|
if (err && err != LFS_ERR_CORRUPT) {
|
||||||
@@ -9943,7 +9949,9 @@ static int lfsr_ftree_flush(lfs_t *lfs,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// below our crystallization threshold? fallback to writing fragments
|
// below our crystallization threshold? fallback to writing fragments
|
||||||
if (crystal_end - crystal_start < lfs->cfg->crystal_thresh) {
|
if (crystal_end - crystal_start < lfs->cfg->crystal_thresh
|
||||||
|
// enough for prog alignment?
|
||||||
|
|| crystal_end - crystal_start < lfs->cfg->prog_size) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -9980,10 +9988,15 @@ static int lfsr_ftree_flush(lfs_t *lfs,
|
|||||||
// wait, found block-level erased-state?
|
// wait, found block-level erased-state?
|
||||||
if (tag == LFSR_TAG_BLOCK
|
if (tag == LFSR_TAG_BLOCK
|
||||||
&& becksum.size != -1
|
&& becksum.size != -1
|
||||||
|
// data not truncated?
|
||||||
&& bptr.data.u.disk.off + lfsr_data_size(&bptr.data)
|
&& bptr.data.u.disk.off + lfsr_data_size(&bptr.data)
|
||||||
== bptr.cksize
|
== bptr.cksize
|
||||||
|
// not clobbering data?
|
||||||
&& crystal_start - (bid-(weight-1))
|
&& crystal_start - (bid-(weight-1))
|
||||||
>= lfsr_data_size(&bptr.data)) {
|
>= lfsr_data_size(&bptr.data)
|
||||||
|
// enough for prog alignment?
|
||||||
|
&& crystal_end - crystal_start
|
||||||
|
>= lfs->cfg->prog_size) {
|
||||||
LFS_ASSERT(bptr.cksize + becksum.size
|
LFS_ASSERT(bptr.cksize + becksum.size
|
||||||
<= lfs->cfg->block_size);
|
<= lfs->cfg->block_size);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user