Merged lfsr_data_progcsum into lfsr_data_prog
Considering that _most_ progs in littlefs needs to be checksummed for future consistency checks, it's not really worth it to have a separate non-checksumming function. Especially when you consider the fanout of the prog extensions for different types. A similar problem, sort of unresolved, is what to do with all the validating functions. I guess we'll cross that bridge when we need to.
This commit is contained in:
@@ -426,27 +426,27 @@ static int lfsr_bd_cmp(lfs_t *lfs,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// program data with optional checksum
|
||||||
static int lfsr_bd_prog(lfs_t *lfs, lfs_block_t block, lfs_off_t off,
|
static int lfsr_bd_prog(lfs_t *lfs, lfs_block_t block, lfs_off_t off,
|
||||||
const void *buffer, lfs_size_t size) {
|
const void *buffer, lfs_size_t size,
|
||||||
|
uint32_t *csum_) {
|
||||||
// check for in-bounds
|
// check for in-bounds
|
||||||
if (off+size > lfs->cfg->block_size) {
|
if (off+size > lfs->cfg->block_size) {
|
||||||
lfs_cache_zero(lfs, &lfs->pcache);
|
lfs_cache_zero(lfs, &lfs->pcache);
|
||||||
return LFS_ERR_RANGE;
|
return LFS_ERR_RANGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return lfs_bd_prog(lfs, &lfs->pcache, &lfs->rcache, false,
|
int err = lfs_bd_prog(lfs, &lfs->pcache, &lfs->rcache, false,
|
||||||
block, off, buffer, size);
|
block, off, buffer, size);
|
||||||
}
|
|
||||||
|
|
||||||
static int lfsr_bd_progcsum(lfs_t *lfs, lfs_block_t block, lfs_off_t off,
|
|
||||||
const void *buffer, lfs_size_t size,
|
|
||||||
uint32_t *csum_) {
|
|
||||||
int err = lfsr_bd_prog(lfs, block, off, buffer, size);
|
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
*csum_ = lfs_crc32c(*csum_, buffer, size);
|
// optional checksum
|
||||||
|
if (csum_) {
|
||||||
|
*csum_ = lfs_crc32c(*csum_, buffer, size);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -454,28 +454,27 @@ static int lfsr_bd_sync(lfs_t *lfs) {
|
|||||||
return lfs_bd_sync(lfs, &lfs->pcache, &lfs->rcache, false);
|
return lfs_bd_sync(lfs, &lfs->pcache, &lfs->rcache, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO do we need this? should everything be checked by crc and validation
|
||||||
|
// be an optional ifdef?
|
||||||
static int lfsr_bd_progvalidate(lfs_t *lfs, lfs_block_t block, lfs_off_t off,
|
static int lfsr_bd_progvalidate(lfs_t *lfs, lfs_block_t block, lfs_off_t off,
|
||||||
const void *buffer, lfs_size_t size) {
|
const void *buffer, lfs_size_t size,
|
||||||
|
uint32_t *csum_) {
|
||||||
// check for in-bounds
|
// check for in-bounds
|
||||||
if (off+size > lfs->cfg->block_size) {
|
if (off+size > lfs->cfg->block_size) {
|
||||||
lfs_cache_zero(lfs, &lfs->pcache);
|
lfs_cache_zero(lfs, &lfs->pcache);
|
||||||
return LFS_ERR_RANGE;
|
return LFS_ERR_RANGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return lfs_bd_prog(lfs, &lfs->pcache, &lfs->rcache, true,
|
int err = lfs_bd_prog(lfs, &lfs->pcache, &lfs->rcache, true,
|
||||||
block, off, buffer, size);
|
block, off, buffer, size);
|
||||||
}
|
|
||||||
|
|
||||||
static int lfsr_bd_progcsumvalidate(lfs_t *lfs,
|
|
||||||
lfs_block_t block, lfs_off_t off,
|
|
||||||
const void *buffer, lfs_size_t size,
|
|
||||||
uint32_t *csum_) {
|
|
||||||
int err = lfsr_bd_progvalidate(lfs, block, off, buffer, size);
|
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
*csum_ = lfs_crc32c(*csum_, buffer, size);
|
if (csum_) {
|
||||||
|
*csum_ = lfs_crc32c(*csum_, buffer, size);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -488,6 +487,7 @@ static int lfsr_bd_erase(lfs_t *lfs, lfs_block_t block) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// Small type-level utilities ///
|
/// Small type-level utilities ///
|
||||||
|
|
||||||
// operations on block pairs
|
// operations on block pairs
|
||||||
@@ -921,13 +921,13 @@ static lfs_ssize_t lfsr_bd_readtag(lfs_t *lfs,
|
|||||||
static lfs_ssize_t lfsr_bd_progtag(lfs_t *lfs,
|
static lfs_ssize_t lfsr_bd_progtag(lfs_t *lfs,
|
||||||
lfs_block_t block, lfs_off_t off,
|
lfs_block_t block, lfs_off_t off,
|
||||||
lfsr_tag_t tag, lfs_size_t weight, lfs_size_t size,
|
lfsr_tag_t tag, lfs_size_t weight, lfs_size_t size,
|
||||||
uint32_t *crc) {
|
uint32_t *csum_) {
|
||||||
// check for underflow issues
|
// check for underflow issues
|
||||||
LFS_ASSERT(weight < 0x80000000);
|
LFS_ASSERT(weight < 0x80000000);
|
||||||
LFS_ASSERT(size < 0x80000000);
|
LFS_ASSERT(size < 0x80000000);
|
||||||
|
|
||||||
// make sure to include the parity of the current crc
|
// make sure to include the parity of the current crc
|
||||||
tag |= lfs_popc(*crc) & 1;
|
tag |= lfs_popc(*csum_) & 1;
|
||||||
|
|
||||||
// encode into an le16 and pair of leb128s
|
// encode into an le16 and pair of leb128s
|
||||||
uint8_t buf[LFSR_TAG_DSIZE];
|
uint8_t buf[LFSR_TAG_DSIZE];
|
||||||
@@ -946,7 +946,7 @@ static lfs_ssize_t lfsr_bd_progtag(lfs_t *lfs,
|
|||||||
}
|
}
|
||||||
d += d_;
|
d += d_;
|
||||||
|
|
||||||
int err = lfsr_bd_progcsum(lfs, block, off, &buf, d, crc);
|
int err = lfsr_bd_prog(lfs, block, off, &buf, d, csum_);
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -1001,7 +1001,7 @@ static inline lfs_size_t lfsr_data_setondisk(lfs_size_t size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// data<->bd interactions
|
// data<->bd interactions
|
||||||
static inline lfs_ssize_t lfsr_data_read(lfs_t *lfs, lfsr_data_t data,
|
static lfs_ssize_t lfsr_data_read(lfs_t *lfs, lfsr_data_t data,
|
||||||
lfs_off_t off, void *buffer, lfs_size_t size) {
|
lfs_off_t off, void *buffer, lfs_size_t size) {
|
||||||
// limit our off/size to data range
|
// limit our off/size to data range
|
||||||
lfs_off_t off_ = lfs_min32(off, lfsr_data_size(data));
|
lfs_off_t off_ = lfs_min32(off, lfsr_data_size(data));
|
||||||
@@ -1023,7 +1023,7 @@ static inline lfs_ssize_t lfsr_data_read(lfs_t *lfs, lfsr_data_t data,
|
|||||||
return size_;
|
return size_;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int lfsr_data_cmp(lfs_t *lfs, lfsr_data_t data,
|
static int lfsr_data_cmp(lfs_t *lfs, lfsr_data_t data,
|
||||||
lfs_off_t off, const void *buffer, lfs_size_t size,
|
lfs_off_t off, const void *buffer, lfs_size_t size,
|
||||||
int *cmp) {
|
int *cmp) {
|
||||||
// limit our off/size to data range
|
// limit our off/size to data range
|
||||||
@@ -1053,10 +1053,9 @@ static inline int lfsr_data_cmp(lfs_t *lfs, lfsr_data_t data,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline lfs_ssize_t lfsr_data_readle32(lfs_t *lfs, lfsr_data_t data,
|
static lfs_ssize_t lfsr_data_readle32(lfs_t *lfs, lfsr_data_t data,
|
||||||
lfs_off_t off, uint32_t *word) {
|
lfs_off_t off, uint32_t *word) {
|
||||||
uint8_t buf[sizeof(uint32_t)];
|
lfs_ssize_t d = lfsr_data_read(lfs, data, off, word, sizeof(uint32_t));
|
||||||
lfs_ssize_t d = lfsr_data_read(lfs, data, off, buf, sizeof(uint32_t));
|
|
||||||
if (d < 0) {
|
if (d < 0) {
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
@@ -1066,11 +1065,11 @@ static inline lfs_ssize_t lfsr_data_readle32(lfs_t *lfs, lfsr_data_t data,
|
|||||||
return LFS_ERR_CORRUPT;
|
return LFS_ERR_CORRUPT;
|
||||||
}
|
}
|
||||||
|
|
||||||
*word = lfs_fromle32_(buf);
|
*word = lfs_fromle32_(word);
|
||||||
return sizeof(uint32_t);
|
return sizeof(uint32_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline lfs_ssize_t lfsr_data_readleb128(lfs_t *lfs, lfsr_data_t data,
|
static lfs_ssize_t lfsr_data_readleb128(lfs_t *lfs, lfsr_data_t data,
|
||||||
lfs_off_t off, uint32_t *word) {
|
lfs_off_t off, uint32_t *word) {
|
||||||
// for 32-bits we can assume worst-case leb128 size is 5-bytes
|
// for 32-bits we can assume worst-case leb128 size is 5-bytes
|
||||||
uint8_t buf[5];
|
uint8_t buf[5];
|
||||||
@@ -1082,12 +1081,10 @@ static inline lfs_ssize_t lfsr_data_readleb128(lfs_t *lfs, lfsr_data_t data,
|
|||||||
return lfs_fromleb128(word, buf, d);
|
return lfs_fromleb128(word, buf, d);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO should we handle this consistently to lfsr_bd_prog/progcsum?
|
|
||||||
// should lfsr_bd_progcsum be rethought?
|
|
||||||
static lfs_ssize_t lfsr_bd_progdata(lfs_t *lfs,
|
static lfs_ssize_t lfsr_bd_progdata(lfs_t *lfs,
|
||||||
lfs_block_t block, lfs_off_t off,
|
lfs_block_t block, lfs_off_t off,
|
||||||
lfsr_data_t data,
|
lfsr_data_t data,
|
||||||
uint32_t *crc) {
|
uint32_t *csum_) {
|
||||||
if (lfsr_data_ondisk(data)) {
|
if (lfsr_data_ondisk(data)) {
|
||||||
// TODO byte-level copies have been a pain point, works for prototyping
|
// TODO byte-level copies have been a pain point, works for prototyping
|
||||||
// but can this be better? configurable? leverage
|
// but can this be better? configurable? leverage
|
||||||
@@ -1101,18 +1098,18 @@ static lfs_ssize_t lfsr_bd_progdata(lfs_t *lfs,
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = lfsr_bd_progcsum(lfs, block, off+i,
|
err = lfsr_bd_prog(lfs, block, off+i,
|
||||||
&dat, 1,
|
&dat, 1,
|
||||||
crc);
|
csum_);
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
int err = lfsr_bd_progcsum(lfs, block, off,
|
int err = lfsr_bd_prog(lfs, block, off,
|
||||||
data.buf.buffer, lfsr_data_size(data),
|
data.buf.buffer, lfsr_data_size(data),
|
||||||
crc);
|
csum_);
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -2003,7 +2000,7 @@ static int lfsr_rbyd_append(lfs_t *lfs, lfsr_rbyd_t *rbyd,
|
|||||||
if (rbyd->off == 0) {
|
if (rbyd->off == 0) {
|
||||||
uint8_t buf[sizeof(uint32_t)];
|
uint8_t buf[sizeof(uint32_t)];
|
||||||
lfs_tole32_(rbyd->rev, &buf);
|
lfs_tole32_(rbyd->rev, &buf);
|
||||||
err = lfsr_bd_progcsum(lfs, rbyd->block, rbyd->off,
|
err = lfsr_bd_prog(lfs, rbyd->block, rbyd->off,
|
||||||
&buf, sizeof(uint32_t), &rbyd->crc);
|
&buf, sizeof(uint32_t), &rbyd->crc);
|
||||||
if (err) {
|
if (err) {
|
||||||
goto failed;
|
goto failed;
|
||||||
@@ -2470,7 +2467,7 @@ static int lfsr_rbyd_commit(lfs_t *lfs, lfsr_rbyd_t *rbyd,
|
|||||||
if (rbyd_.off == 0) {
|
if (rbyd_.off == 0) {
|
||||||
uint8_t buf[sizeof(uint32_t)];
|
uint8_t buf[sizeof(uint32_t)];
|
||||||
lfs_tole32_(rbyd_.rev, &buf);
|
lfs_tole32_(rbyd_.rev, &buf);
|
||||||
err = lfsr_bd_progcsum(lfs, rbyd_.block, rbyd_.off,
|
err = lfsr_bd_prog(lfs, rbyd_.block, rbyd_.off,
|
||||||
&buf, sizeof(uint32_t), &rbyd_.crc);
|
&buf, sizeof(uint32_t), &rbyd_.crc);
|
||||||
if (err) {
|
if (err) {
|
||||||
goto failed;
|
goto failed;
|
||||||
@@ -2547,7 +2544,7 @@ static int lfsr_rbyd_commit(lfs_t *lfs, lfsr_rbyd_t *rbyd,
|
|||||||
}
|
}
|
||||||
rbyd_.off += d_;
|
rbyd_.off += d_;
|
||||||
|
|
||||||
err = lfsr_bd_progcsum(lfs, rbyd_.block, rbyd_.off,
|
err = lfsr_bd_prog(lfs, rbyd_.block, rbyd_.off,
|
||||||
buf, d, &rbyd_.crc);
|
buf, d, &rbyd_.crc);
|
||||||
if (err) {
|
if (err) {
|
||||||
goto failed;
|
goto failed;
|
||||||
@@ -2592,7 +2589,7 @@ static int lfsr_rbyd_commit(lfs_t *lfs, lfsr_rbyd_t *rbyd,
|
|||||||
}
|
}
|
||||||
lfs_tole32_(rbyd_.crc, &buf[2+1+5]);
|
lfs_tole32_(rbyd_.crc, &buf[2+1+5]);
|
||||||
|
|
||||||
err = lfsr_bd_prog(lfs, rbyd_.block, rbyd_.off, buf, 2+1+5+4);
|
err = lfsr_bd_prog(lfs, rbyd_.block, rbyd_.off, buf, 2+1+5+4, NULL);
|
||||||
if (err) {
|
if (err) {
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
@@ -4115,10 +4112,11 @@ static int lfsr_mdir_fetch(lfs_t *lfs, lfsr_mdir_t *mdir, lfsr_mpair_t mpair,
|
|||||||
uint32_t revs[2] = {0, 0};
|
uint32_t revs[2] = {0, 0};
|
||||||
for (int i = 0; i < 2; i++) {
|
for (int i = 0; i < 2; i++) {
|
||||||
int err = lfsr_bd_read(lfs, mpair.blocks[0], 0, 0,
|
int err = lfsr_bd_read(lfs, mpair.blocks[0], 0, 0,
|
||||||
&revs[0], sizeof(revs[0]));
|
&revs[0], sizeof(uint32_t));
|
||||||
if (err && err != LFS_ERR_CORRUPT) {
|
if (err && err != LFS_ERR_CORRUPT) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
revs[i] = lfs_fromle32_(&revs[i]);
|
||||||
|
|
||||||
if (i == 0
|
if (i == 0
|
||||||
|| err == LFS_ERR_CORRUPT
|
|| err == LFS_ERR_CORRUPT
|
||||||
|
|||||||
Reference in New Issue
Block a user