Carved out ckreads, disabled at compile-time by default

This moves all ckread-related logic behind the new opt-in compile-time
LFS_CKREADS flag. So in order to use ckreads you need to 1. define
LFS_CKREADS at compile time, and 2. pass LFS_M_CKREADS during
lfsr_mount.

This was always the plan since, even if ckreads worked perfectly, it
adds a significant amount of baggage (stack mostly) to track the
ck context of all reads.

---

This is the first non-trivial opt-in define in littlefs, so more test
framework features!

test.py and build.py now support the optional ifdef attribute, which
makes it easy to indicate a test suite/case should not be compiled when
a feature is missing.

Also interesting to note is the addition of LFS_IFDEF_CKREADS, which
solves several issues (and general ugliness) related to #ifdefs in
expression. For example:

  // does not compile :( (can't embed ifdefs in macros)
  LFS_ASSERT(flags == (
          LFS_M_CKPROGS
              #ifdef LFS_CKREADS
              | LFS_M_CKREADS
              #endif
              ))

  // does compile :)
  LFS_ASSERT(flags == (
          LFS_M_CKPROGS
              | LFS_IFDEF_CKREADS(LFS_M_CKREADS, 0)));

---

This brings us way back down to our pre-ckread levels of code/stack:

                   code          stack
  before-ckreads: 36352           2672
  ckreads:        38060 (+4.7%)   3056 (+14.4%)
  after-ckreads:  36428 (+0.2%)   2680 (+0.3%)

Unfortunately, we do end up with a bit more code cost than where we
started. Mainly due to code moving around to support the ckread
infrastructure:

                   code          stack
  lfsr_bd_readtag:  +52 (+23.2%)    +8 (+10.0%)
  lfsr_rbyd_fetch:  +36 (+5.0%)     +8 (+6.2%, cold)
  lfs_toleb128:     -12 (-25.0%)    -4 (-20.0%, cold)
  total:            +76 (+0.2%)     +8 (+0.3%)

But oh well. Note that some of these changes are good even without
ckreads, such as only parsing the last ecksum tag.
This commit is contained in:
Christopher Haster
2024-08-11 18:18:28 -05:00
parent 185f209dbf
commit 6e2af5bf80
9 changed files with 352 additions and 53 deletions
+210 -46
View File
@@ -695,31 +695,44 @@ static int lfsr_bd_set(lfs_t *lfs, lfs_block_t block, lfs_size_t off,
/// lfsr_ck_t stuff ///
#ifdef LFS_CKREADS
#define LFSR_CK_ISPARITY 0x80000000
#endif
#ifdef LFS_CKREADS
#define LFSR_CK_CKSUM(_cksize, _cksum) \
((lfsr_ck_t){ \
.cksize=_cksize, \
.u.cksum=_cksum})
#endif
#ifdef LFS_CKREADS
#define LFSR_CK_PARITY(_ckoff, _cksize) \
((lfsr_ck_t){ \
.cksize=LFSR_CK_ISPARITY | (_cksize), \
.u.ckoff=_ckoff})
#endif
// ck helpers
#ifdef LFS_CKREADS
static inline bool lfsr_ck_isparity(lfsr_ck_t ck) {
return ck.cksize & LFSR_CK_ISPARITY;
}
#endif
#ifdef LFS_CKREADS
static inline bool lfsr_ck_iscksum(lfsr_ck_t ck) {
return !(ck.cksize & LFSR_CK_ISPARITY);
}
#endif
#ifdef LFS_CKREADS
static inline lfs_size_t lfsr_ck_cksize(lfsr_ck_t ck) {
return ck.cksize & ~LFSR_CK_ISPARITY;
}
#endif
#ifdef LFS_CKREADS
static inline lfs_size_t lfsr_ck_ckoff(lfsr_ck_t ck) {
if (lfsr_ck_isparity(ck)) {
return ck.u.ckoff;
@@ -727,22 +740,30 @@ static inline lfs_size_t lfsr_ck_ckoff(lfsr_ck_t ck) {
return 0;
}
}
#endif
// lfsr_tailck_t stuff
//
// tailck tracks the most recent trunk's parity so we can parity-check
// if it hasn't been written to disk yet
#ifdef LFS_CKREADS
#define LFSR_TAILCK_PARITY 0x80000000
#endif
#ifdef LFS_CKREADS
static inline bool lfsr_tailck_parity(const lfsr_tailck_t *tailck) {
return tailck->ckoff & LFSR_TAILCK_PARITY;
}
#endif
#ifdef LFS_CKREADS
static inline lfs_size_t lfsr_tailck_ckoff(const lfsr_tailck_t *tailck) {
return tailck->ckoff & ~LFSR_TAILCK_PARITY;
}
#endif
#ifdef LFS_CKREADS
// read the pesky parity byte from disk
static lfs_sbool_t lfsr_bd_readparity(lfs_t *lfs,
lfs_block_t block, lfs_size_t off, lfs_size_t hint) {
@@ -774,7 +795,9 @@ static lfs_sbool_t lfsr_bd_readparity(lfs_t *lfs,
return p >> 7;
}
}
#endif
#ifdef LFS_CKREADS
static lfs_ssize_t lfsr_bd_ckprefix(lfs_t *lfs,
lfs_block_t block, lfs_size_t off, lfs_size_t hint,
lfsr_ck_t ck,
@@ -804,7 +827,9 @@ static lfs_ssize_t lfsr_bd_ckprefix(lfs_t *lfs,
// earlier, otherwise we'd have real problems with hint=-1!
return hint_ - (off-lfsr_ck_ckoff(ck));
}
#endif
#ifdef LFS_CKREADS
static int lfsr_bd_cksuffix(lfs_t *lfs,
lfs_block_t block, lfs_size_t off, lfs_size_t hint,
lfsr_ck_t ck,
@@ -861,7 +886,9 @@ static int lfsr_bd_cksuffix(lfs_t *lfs,
return 0;
}
#endif
#ifdef LFS_CKREADS
// caching read with parity/checksum checks
//
// the main downside of ckreads is we need to read all data that
@@ -906,7 +933,9 @@ static int lfsr_bd_readck_(lfs_t *lfs,
return 0;
}
#endif
#ifdef LFS_CKREADS
// needed in lfsr_bd_readck
static inline bool lfsr_m_isckreads(uint32_t flags);
@@ -926,6 +955,16 @@ static int lfsr_bd_readck(lfs_t *lfs,
buffer, size);
}
}
#endif
// redirect to lfsr_bd_read if not checking reads
#ifdef LFS_CKREADS
#define LFSR_BD_READCK(_lfs, _block, _off, _hint, _buffer, _size, _ck) \
lfsr_bd_readck(_lfs, _block, _off, _hint, _buffer, _size, _ck)
#else
#define LFSR_BD_READCK(_lfs, _block, _off, _hint, _buffer, _size, _ck) \
lfsr_bd_read(_lfs, _block, _off, _hint, _buffer, _size)
#endif
// these could probably be a bit better deduplicated with their
// unchecked counterparts, but we don't generally use both at the same
@@ -933,6 +972,7 @@ static int lfsr_bd_readck(lfs_t *lfs,
//
// we'd also need to worry about early termination in lfsr_bd_cmp/cmpck
#ifdef LFS_CKREADS
static lfs_scmp_t lfsr_bd_cmpck_(lfs_t *lfs,
lfs_block_t block, lfs_size_t off, lfs_size_t hint,
const void *buffer, lfs_size_t size,
@@ -991,7 +1031,9 @@ static lfs_scmp_t lfsr_bd_cmpck_(lfs_t *lfs,
return cmp;
}
#endif
#ifdef LFS_CKREADS
static lfs_scmp_t lfsr_bd_cmpck(lfs_t *lfs,
lfs_block_t block, lfs_size_t off, lfs_size_t hint,
const void *buffer, lfs_size_t size,
@@ -1008,7 +1050,18 @@ static lfs_scmp_t lfsr_bd_cmpck(lfs_t *lfs,
buffer, size);
}
}
#endif
// redirect to lfsr_bd_cmp if not checking reads
#ifdef LFS_CKREADS
#define LFSR_BD_CMPCK(_lfs, _block, _off, _hint, _buffer, _size, _ck) \
lfsr_bd_cmpck(_lfs, _block, _off, _hint, _buffer, _size, _ck)
#else
#define LFSR_BD_CMPCK(_lfs, _block, _off, _hint, _buffer, _size, _ck) \
lfsr_bd_cmp(_lfs, _block, _off, _hint, _buffer, _size)
#endif
#ifdef LFS_CKREADS
static int lfsr_bd_cpyck_(lfs_t *lfs,
lfs_block_t dst_block, lfs_size_t dst_off,
lfs_block_t src_block, lfs_size_t src_off, lfs_size_t hint,
@@ -1080,7 +1133,9 @@ static int lfsr_bd_cpyck_(lfs_t *lfs,
return 0;
}
#endif
#ifdef LFS_CKREADS
static int lfsr_bd_cpyck(lfs_t *lfs,
lfs_block_t dst_block, lfs_size_t dst_off,
lfs_block_t src_block, lfs_size_t src_off, lfs_size_t hint,
@@ -1103,6 +1158,35 @@ static int lfsr_bd_cpyck(lfs_t *lfs,
cksum, align);
}
}
#endif
// redirect to lfsr_bd_cpy if not checking reads
#ifdef LFS_CKREADS
#define LFSR_BD_CPYCK(_lfs, \
_dst_block, _dst_off, \
_src_block, _src_off, _hint, \
_size, \
_ck, \
_cksum, _align) \
lfsr_bd_cpyck(_lfs, \
_dst_block, _dst_off, \
_src_block, _src_off, _hint, \
_size, \
_ck, \
_cksum, _align)
#else
#define LFSR_BD_CPYCK(_lfs, \
_dst_block, _dst_off, \
_src_block, _src_off, _hint, \
_size, \
_ck, \
_cksum, _align) \
lfsr_bd_cpy(_lfs, \
_dst_block, _dst_off, \
_src_block, _src_off, _hint, \
_size, \
_cksum, _align)
#endif
@@ -1625,6 +1709,7 @@ static lfs_ssize_t lfsr_bd_readtag(lfs_t *lfs,
*cksum = lfs_crc32c(*cksum, tag_buf, d);
}
#ifdef LFS_CKREADS
// check the parity if we're checking reads and not already
// calculating a checksum
//
@@ -1649,6 +1734,7 @@ static lfs_ssize_t lfsr_bd_readtag(lfs_t *lfs,
return err;
}
}
#endif
// save what we found, clearing the valid bit, we don't need it
// anymore
@@ -1720,28 +1806,35 @@ static lfs_ssize_t lfsr_bd_progtag(lfs_t *lfs,
.size=_size, \
.u.buffer=(const void*)(_buffer)})
// TODO
#if 0
#define LFSR_DATA_DISK(_block, _off, _size) \
((lfsr_data_t){ \
.size=LFSR_DATA_ONDISK | (_size), \
.u.disk.block=_block, \
.u.disk.off=_off})
#endif
#ifdef LFS_CKREADS
#define LFSR_DATA_DISKCKSUM(_block, _off, _size, _cksize, _cksum) \
((lfsr_data_t){ \
.size=LFSR_DATA_ONDISK | (_size), \
.u.disk.block=_block, \
.u.disk.off=_off, \
.u.disk.ck=LFSR_CK_CKSUM(_cksize, _cksum)})
#else
#define LFSR_DATA_DISKCKSUM(_block, _off, _size, _cksize, _cksum) \
((lfsr_data_t){ \
.size=LFSR_DATA_ONDISK | (_size), \
.u.disk.block=_block, \
.u.disk.off=_off})
#endif
#ifdef LFS_CKREADS
#define LFSR_DATA_DISKPARITY(_block, _off, _size, _ckoff, _cksize) \
((lfsr_data_t){ \
.size=LFSR_DATA_ONDISK | (_size), \
.u.disk.block=_block, \
.u.disk.off=_off, \
.u.disk.ck=LFSR_CK_PARITY(_ckoff, _cksize)})
#else
#define LFSR_DATA_DISKPARITY(_block, _off, _size, _ckoff, _cksize) \
((lfsr_data_t){ \
.size=LFSR_DATA_ONDISK | (_size), \
.u.disk.block=_block, \
.u.disk.off=_off})
#endif
// data helpers
static inline bool lfsr_data_ondisk(lfsr_data_t data) {
@@ -1806,7 +1899,7 @@ static lfs_ssize_t lfsr_data_read(lfs_t *lfs, lfsr_data_t *data,
// on-disk?
if (lfsr_data_ondisk(*data)) {
int err = lfsr_bd_readck(lfs,
int err = LFSR_BD_READCK(lfs,
data->u.disk.block, data->u.disk.off,
// note our hint includes the full data range
lfsr_data_size(*data),
@@ -1895,7 +1988,7 @@ static lfs_scmp_t lfsr_data_cmp(lfs_t *lfs, lfsr_data_t data,
// on-disk?
if (lfsr_data_ondisk(data)) {
int cmp = lfsr_bd_cmpck(lfs,
int cmp = LFSR_BD_CMPCK(lfs,
// note the 0 hint, we don't usually use any following data
data.u.disk.block, data.u.disk.off, 0,
buffer, d,
@@ -1948,7 +2041,7 @@ static int lfsr_bd_progdata(lfs_t *lfs,
uint32_t *cksum, bool align) {
// on-disk?
if (lfsr_data_ondisk(data)) {
int err = lfsr_bd_cpyck(lfs, block, off,
int err = LFSR_BD_CPYCK(lfs, block, off,
data.u.disk.block, data.u.disk.off, lfsr_data_size(data),
lfsr_data_size(data),
data.u.disk.ck,
@@ -2386,6 +2479,25 @@ static int lfsr_data_readecksum(lfs_t *lfs, lfsr_data_t *data,
#define LFSR_DATA_BPTR(_bptr) \
LFSR_DATA_BPTR_(_bptr, (uint8_t[LFSR_BPTR_DSIZE]){0})
// checked reads introduces ck info into lfsr_data_t that we don't want
// to unnecessarily duplicate, so accessing ck info gets annoyingly
// messy...
static inline lfs_size_t lfsr_bptr_cksize(const lfsr_bptr_t *bptr) {
#ifdef LFS_CKREADS
return bptr->data.u.disk.ck.cksize;
#else
return bptr->cksize;
#endif
}
static inline uint32_t lfsr_bptr_cksum(const lfsr_bptr_t *bptr) {
#ifdef LFS_CKREADS
return bptr->data.u.disk.ck.u.cksum;
#else
return bptr->cksum;
#endif
}
static lfsr_data_t lfsr_data_frombptr(const lfsr_bptr_t *bptr,
uint8_t buffer[static LFSR_BPTR_DSIZE]) {
// size should not exceed 28-bits
@@ -2395,7 +2507,7 @@ static lfsr_data_t lfsr_data_frombptr(const lfsr_bptr_t *bptr,
// off should not exceed 28-bits
LFS_ASSERT(bptr->data.u.disk.off <= 0x0fffffff);
// cksize should not exceed 28-bits
LFS_ASSERT(bptr->data.u.disk.ck.cksize <= 0x0fffffff);
LFS_ASSERT(lfsr_bptr_cksize(bptr) <= 0x0fffffff);
lfs_ssize_t d = 0;
// write the block, offset, size
@@ -2418,13 +2530,13 @@ static lfsr_data_t lfsr_data_frombptr(const lfsr_bptr_t *bptr,
d += d_;
// write the cksize, cksum
d_ = lfs_toleb128(bptr->data.u.disk.ck.cksize, &buffer[d], 4);
d_ = lfs_toleb128(lfsr_bptr_cksize(bptr), &buffer[d], 4);
if (d_ < 0) {
LFS_UNREACHABLE();
}
d += d_;
lfs_tole32_(bptr->data.u.disk.ck.u.cksum, &buffer[d]);
lfs_tole32_(lfsr_bptr_cksum(bptr), &buffer[d]);
d += 4;
return LFSR_DATA_BUF(buffer, d);
@@ -2449,12 +2561,18 @@ static int lfsr_data_readbptr(lfs_t *lfs, lfsr_data_t *data,
}
// read the cksize, cksum
err = lfsr_data_readlleb128(lfs, data, &bptr->data.u.disk.ck.cksize);
err = lfsr_data_readlleb128(lfs, data,
LFS_IFDEF_CKREADS(
&bptr->data.u.disk.ck.cksize,
&bptr->cksize));
if (err) {
return err;
}
err = lfsr_data_readle32(lfs, data, &bptr->data.u.disk.ck.u.cksum);
err = lfsr_data_readle32(lfs, data,
LFS_IFDEF_CKREADS(
&bptr->data.u.disk.ck.u.cksum,
&bptr->cksum));
if (err) {
return err;
}
@@ -2470,20 +2588,20 @@ static int lfsr_bptr_ck(lfs_t *lfs, const lfsr_bptr_t *bptr) {
uint32_t cksum = 0;
int err = lfsr_bd_cksum(lfs,
bptr->data.u.disk.block, 0, 0,
bptr->data.u.disk.ck.cksize,
lfsr_bptr_cksize(bptr),
&cksum);
if (err) {
return err;
}
// test that our cksum matches what's expected
if (cksum != bptr->data.u.disk.ck.u.cksum) {
if (cksum != lfsr_bptr_cksum(bptr)) {
LFS_ERROR("Found bptr cksum mismatch "
"0x%"PRIx32".%"PRIx32" %"PRId32", "
"cksum %08"PRIx32" (!= %08"PRIx32")",
bptr->data.u.disk.block, 0,
bptr->data.u.disk.ck.cksize,
cksum, bptr->data.u.disk.ck.u.cksum);
lfsr_bptr_cksize(bptr),
cksum, lfsr_bptr_cksum(bptr));
return LFS_ERR_CORRUPT;
}
@@ -3125,6 +3243,7 @@ static int lfsr_rbyd_appendtag(lfs_t *lfs, lfsr_rbyd_t *rbyd,
rbyd->eoff += d;
#ifdef LFS_CKREADS
// keep track of most recent parity
lfs->tailck.ckblock = rbyd->blocks[0];
lfs->tailck.ckoff
@@ -3132,6 +3251,7 @@ static int lfsr_rbyd_appendtag(lfs_t *lfs, lfsr_rbyd_t *rbyd,
lfs_parity(rbyd->cksum) ^ lfsr_rbyd_isperturb(rbyd)
) << (8*sizeof(lfs_size_t)-1))
| lfsr_rbyd_eoff(rbyd);
#endif
return 0;
}
@@ -3154,6 +3274,7 @@ static int lfsr_rbyd_appendcat(lfs_t *lfs, lfsr_rbyd_t *rbyd,
rbyd->eoff += lfsr_cat_size(cat, count);
#ifdef LFS_CKREADS
// keep track of most recent parity
lfs->tailck.ckblock = rbyd->blocks[0];
lfs->tailck.ckoff
@@ -3161,6 +3282,7 @@ static int lfsr_rbyd_appendcat(lfs_t *lfs, lfsr_rbyd_t *rbyd,
lfs_parity(rbyd->cksum) ^ lfsr_rbyd_isperturb(rbyd)
) << (8*sizeof(lfs_size_t)-1))
| lfsr_rbyd_eoff(rbyd);
#endif
return 0;
}
@@ -6565,9 +6687,11 @@ static inline bool lfsr_m_isckprogs(uint32_t flags) {
return flags & LFS_M_CKPROGS;
}
#ifdef LFS_CKREADS
static inline bool lfsr_m_isckreads(uint32_t flags) {
return flags & LFS_M_CKREADS;
}
#endif
static inline bool lfsr_m_isflush(uint32_t flags) {
return flags & LFS_M_FLUSH;
@@ -7260,7 +7384,7 @@ static int lfsr_mdir_swap__(lfs_t *lfs, lfsr_mdir_t *mdir_,
// first thing we need to do is read our current revision count
uint32_t rev;
int err = lfsr_bd_readck(lfs, mdir->rbyd.blocks[0], 0, 0,
int err = LFSR_BD_READCK(lfs, mdir->rbyd.blocks[0], 0, 0,
&rev, sizeof(uint32_t),
LFSR_CK_PARITY(0, sizeof(uint32_t)));
if (err && err != LFS_ERR_CORRUPT) {
@@ -11051,7 +11175,13 @@ static int lfsr_file_carve(lfs_t *lfs, lfsr_file_t *file,
LFSR_TAG_GROW | LFSR_TAG_SUB | LFSR_TAG_BLOCK,
-(bid+1 - pos),
LFSR_DATA_BPTR_(
(&(lfsr_bptr_t){.data=left_slice_}),
LFS_IFDEF_CKREADS(
(&(lfsr_bptr_t){
.data=left_slice_}),
(&(lfsr_bptr_t){
.data=left_slice_,
.cksize=bptr_.cksize,
.cksum=bptr_.cksum})),
left.buf));
} else {
@@ -11103,7 +11233,13 @@ static int lfsr_file_carve(lfs_t *lfs, lfsr_file_t *file,
tag_,
bid+1 - (pos+weight),
LFSR_DATA_BPTR_(
(&(lfsr_bptr_t){.data=right_slice_}),
LFS_IFDEF_CKREADS(
(&(lfsr_bptr_t){
.data=right_slice_}),
(&(lfsr_bptr_t){
.data=right_slice_,
.cksize=bptr_.cksize,
.cksum=bptr_.cksum})),
right.buf));
} else {
@@ -11343,6 +11479,12 @@ static int lfsr_file_flush_(lfs_t *lfs, lfsr_file_t *file,
}
bptr.data = LFSR_DATA_DISKCKSUM(block, 0, 0, 0, 0);
LFS_IFDEF_CKREADS(
bptr.data.u.disk.ck.cksize,
bptr.cksize) = 0;
LFS_IFDEF_CKREADS(
bptr.data.u.disk.ck.u.cksum,
bptr.cksum) = 0;
compact:;
// compact data into our block
@@ -11371,9 +11513,11 @@ static int lfsr_file_flush_(lfs_t *lfs, lfsr_file_t *file,
d,
size - (pos_ - pos));
int err = lfsr_bd_prog(lfs, bptr.data.u.disk.block,
bptr.data.u.disk.ck.cksize,
lfsr_bptr_cksize(&bptr),
&buffer[pos_ - pos], d_,
&bptr.data.u.disk.ck.u.cksum, true);
LFS_IFDEF_CKREADS(
&bptr.data.u.disk.ck.u.cksum,
&bptr.cksum), true);
if (err) {
LFS_ASSERT(err != LFS_ERR_RANGE);
// bad prog? try another block
@@ -11384,7 +11528,9 @@ static int lfsr_file_flush_(lfs_t *lfs, lfsr_file_t *file,
}
pos_ += d_;
bptr.data.u.disk.ck.cksize += d_;
LFS_IFDEF_CKREADS(
bptr.data.u.disk.ck.cksize,
bptr.cksize) += d_;
d -= d_;
}
@@ -11430,11 +11576,13 @@ static int lfsr_file_flush_(lfs_t *lfs, lfsr_file_t *file,
lfsr_data_size(bptr_.data)
- (pos_ - (bid_-(weight_-1))));
err = lfsr_bd_progdata(lfs, bptr.data.u.disk.block,
bptr.data.u.disk.ck.cksize,
lfsr_bptr_cksize(&bptr),
lfsr_data_slice(bptr_.data,
pos_ - (bid_-(weight_-1)),
d_),
&bptr.data.u.disk.ck.u.cksum, true);
LFS_IFDEF_CKREADS(
&bptr.data.u.disk.ck.u.cksum,
&bptr.cksum), true);
if (err) {
LFS_ASSERT(err != LFS_ERR_RANGE);
// bad prog? try another block
@@ -11445,7 +11593,9 @@ static int lfsr_file_flush_(lfs_t *lfs, lfsr_file_t *file,
}
pos_ += d_;
bptr.data.u.disk.ck.cksize += d_;
LFS_IFDEF_CKREADS(
bptr.data.u.disk.ck.cksize,
bptr.cksize) += d_;
d -= d_;
}
@@ -11455,9 +11605,11 @@ static int lfsr_file_flush_(lfs_t *lfs, lfsr_file_t *file,
// found a hole? fill with zeros
int err = lfsr_bd_set(lfs,
bptr.data.u.disk.block, bptr.data.u.disk.ck.cksize,
bptr.data.u.disk.block, lfsr_bptr_cksize(&bptr),
0, d,
&bptr.data.u.disk.ck.u.cksum, true);
LFS_IFDEF_CKREADS(
&bptr.data.u.disk.ck.u.cksum,
&bptr.cksum), true);
if (err) {
LFS_ASSERT(err != LFS_ERR_RANGE);
// bad prog? try another block
@@ -11468,19 +11620,25 @@ static int lfsr_file_flush_(lfs_t *lfs, lfsr_file_t *file,
}
pos_ += d;
bptr.data.u.disk.ck.cksize += d;
LFS_IFDEF_CKREADS(
bptr.data.u.disk.ck.cksize,
bptr.cksize) += d;
}
// A bit of a hack here, we need to truncate our block to prog_size
// alignment to avoid padding issues. Doing this retroactively to
// the pcache greatly simplifies the above loop, though we may end
// up reading more than is strictly necessary.
lfs_ssize_t d = bptr.data.u.disk.ck.cksize % lfs->cfg->prog_size;
lfs_ssize_t d = lfsr_bptr_cksize(&bptr) % lfs->cfg->prog_size;
lfs->pcache.size -= d;
bptr.data.u.disk.ck.cksize -= d;
LFS_IFDEF_CKREADS(
bptr.data.u.disk.ck.cksize,
bptr.cksize) -= d;
// finalize our write
int err = lfsr_bd_flush(lfs, &bptr.data.u.disk.ck.u.cksum, true);
int err = lfsr_bd_flush(lfs, LFS_IFDEF_CKREADS(
&bptr.data.u.disk.ck.u.cksum,
&bptr.cksum), true);
if (err) {
// bad prog? try another block
if (err == LFS_ERR_CORRUPT) {
@@ -11490,14 +11648,14 @@ static int lfsr_file_flush_(lfs_t *lfs, lfsr_file_t *file,
}
// prepare our block pointer
LFS_ASSERT(bptr.data.u.disk.ck.cksize > 0);
LFS_ASSERT(bptr.data.u.disk.ck.cksize <= lfs->cfg->block_size);
LFS_ASSERT(lfsr_bptr_cksize(&bptr) > 0);
LFS_ASSERT(lfsr_bptr_cksize(&bptr) <= lfs->cfg->block_size);
bptr.data = LFSR_DATA_DISKCKSUM(
bptr.data.u.disk.block,
bptr.data.u.disk.off,
bptr.data.u.disk.ck.cksize - bptr.data.u.disk.off,
bptr.data.u.disk.ck.cksize,
bptr.data.u.disk.ck.u.cksum);
lfsr_bptr_cksize(&bptr) - bptr.data.u.disk.off,
lfsr_bptr_cksize(&bptr),
lfsr_bptr_cksum(&bptr));
lfs_off_t block_end = block_start + lfsr_data_size(bptr.data);
// and write it into our tree
@@ -11512,9 +11670,9 @@ static int lfsr_file_flush_(lfs_t *lfs, lfsr_file_t *file,
}
// keep track of any remaining erased-state
if (bptr.data.u.disk.ck.cksize < lfs->cfg->block_size) {
if (lfsr_bptr_cksize(&bptr) < lfs->cfg->block_size) {
file->eblock = bptr.data.u.disk.block;
file->eoff = bptr.data.u.disk.ck.cksize;
file->eoff = lfsr_bptr_cksize(&bptr);
}
// note compacting fragments -> blocks may not actually make any
@@ -12476,9 +12634,11 @@ static int lfs_init(lfs_t *lfs, uint32_t flags,
}
}
#ifdef LFS_CKREADS
// setup tailck, nothing should actually check off=0
lfs->tailck.ckblock = 0;
lfs->tailck.ckoff = 0;
#endif
// setup lookahead buffer, note mount finishes initializing this after
// we establish a decent pseudo-random seed
@@ -13184,7 +13344,7 @@ int lfsr_mount(lfs_t *lfs, uint32_t flags,
LFS_M_RDWR
| LFS_M_RDONLY
| LFS_M_CKPROGS
| LFS_M_CKREADS
| LFS_IFDEF_CKREADS(LFS_M_CKREADS, 0)
| LFS_M_FLUSH
| LFS_M_SYNC
| LFS_M_MTREEONLY
@@ -13342,7 +13502,11 @@ static int lfsr_formatinited(lfs_t *lfs) {
int lfsr_format(lfs_t *lfs, const struct lfs_config *cfg) {
// TODO hmmm, should lfsr_format take flags?
int err = lfs_init(lfs, LFS_M_RDWR | LFS_M_CKPROGS | LFS_M_CKREADS, cfg);
int err = lfs_init(lfs,
LFS_M_RDWR
| LFS_M_CKPROGS
| LFS_IFDEF_CKREADS(LFS_M_CKREADS, 0),
cfg);
if (err) {
return err;
}
@@ -13373,7 +13537,7 @@ int lfsr_fs_stat(lfs_t *lfs, struct lfs_fsinfo *fsinfo) {
fsinfo->flags = lfs->flags & (
LFS_I_RDONLY
| LFS_I_CKPROGS
| LFS_I_CKREADS
| LFS_IFDEF_CKREADS(LFS_I_CKREADS, 0)
| LFS_I_FLUSH
| LFS_I_SYNC
| LFS_I_UNCOMPACTED);