Trying to handle ecksums correctly when erased=>LFS_ERR_CORRUPT
It should be legal for block devices to return LFS_ERR_CORRUPT when
erased, this is common on devices with ECC, where the erased-state is
not valid ECC and results in LFS_ERR_CORRUPT.
If anything this is a better indicator than fixed-value erased-state,
but we need to make sure we track this with our ecksums consistently.
This gets a bit arbitrary.
Normally:
valid = m[0] & 0x80
cksum = crc32c(m)
If bd_read returns LFS_ERR_CORRUPT:
valid = 0 & 0x80
cksum = crc32c([])
Yeah, implementing this gets a bit funky, but the code cost is trivial:
code stack
before: 33924 2824
after: 33928 (+0.0%) 2824 (+0.0%)
Note this is only best effort right now, we really need tests over
erased=>LFS_ERR_CORRUPT...
This commit is contained in:
@@ -2384,7 +2384,6 @@ static int lfsr_rbyd_fetch(lfs_t *lfs, lfsr_rbyd_t *rbyd,
|
||||
if (lfsr_rbyd_eoff(rbyd) < lfs->cfg->block_size
|
||||
&& lfsr_rbyd_eoff(rbyd) % lfs->cfg->prog_size == 0
|
||||
&& ecksum.cksize != -1) {
|
||||
// TODO is this correct for erased=corrupt?
|
||||
uint8_t e = 0;
|
||||
err = lfsr_bd_read(lfs,
|
||||
rbyd->blocks[0], lfsr_rbyd_eoff(rbyd), ecksum.cksize,
|
||||
@@ -2397,7 +2396,10 @@ static int lfsr_rbyd_fetch(lfs_t *lfs, lfsr_rbyd_t *rbyd,
|
||||
if ((e >> 7) != lfsr_rbyd_parity(rbyd)) {
|
||||
// check that erased-state matches our checksum, if this fails
|
||||
// most likely a write was interrupted
|
||||
uint32_t ecksum_ = lfs_crc32c(0, &e, 1);
|
||||
uint32_t ecksum_ = 0;
|
||||
if (err != LFS_ERR_CORRUPT) {
|
||||
ecksum_ = lfs_crc32c(0, &e, 1);
|
||||
}
|
||||
int err = lfsr_bd_cksum(lfs,
|
||||
rbyd->blocks[0], lfsr_rbyd_eoff(rbyd)+1, 0,
|
||||
ecksum.cksize-1,
|
||||
@@ -3458,7 +3460,10 @@ static int lfsr_rbyd_appendcksum(lfs_t *lfs, lfsr_rbyd_t *rbyd) {
|
||||
// calculate the erased-state checksum
|
||||
lfsr_ecksum_t ecksum;
|
||||
ecksum.cksize = lfs->cfg->prog_size;
|
||||
ecksum.cksum = lfs_crc32c(0, &e, 1);
|
||||
ecksum.cksum = 0;
|
||||
if (err != LFS_ERR_CORRUPT) {
|
||||
ecksum.cksum = lfs_crc32c(0, &e, 1);
|
||||
}
|
||||
err = lfsr_bd_cksum(lfs,
|
||||
rbyd->blocks[0], off_+1, ecksum.cksize-1,
|
||||
ecksum.cksize-1,
|
||||
|
||||
Reference in New Issue
Block a user