Relegated ckreads -> ckparity

Ckparity is pretty flawed in littlefs, for several reasons. The biggest
one being that we can't even reliably detect single-bit errors.

But! It can still provide an extra layer of safety in a system where you
don't care about the extra code/stack cost.

And, for ckreads, performance cost...

Performance isn't a big problem for parity-checking. We can assume
metadata tags are going to relatively small (and can be controlled by
fragment_size). But for data checksums, ckreads risks O(b^2) when
performing many small reads, which can be a bit of a problem.

And since ckreads doesn't really prove anything interesting about the
system anymore, it makes sense to unbundle these two checks, rename
ckreads -> ckparity, and limit it to only checking parity bits.

This way, you can enable ckparity for a bit of extra safety, with a
code/stack cost hit, but without sacrificing performance.

---

I was hoping more code/stack savings, but since we still need to track
parity context in lfsr_data_t, and still need to intercept bd_read/cmp/
cpy calls that reference metadata, we end up needing to keep most of
the ck circuitry around:

                    code          stack
  default before:  36464           2672
  default after:   36464 (+0.0%)   2672 (+0.0%)

                    code          stack
  ckparity before: 38036           3080
  ckparity after:  38024 (-0.0%)   3080 (+0.0%)

We even end up still tracking checksum context for bptrs! Maybe we
should just go ahead and add ckcksums as a joke...
This commit is contained in:
Christopher Haster
2024-08-16 14:51:59 -05:00
parent fa04c41f5c
commit 2d121c8d19
5 changed files with 475 additions and 611 deletions
+17 -17
View File
@@ -156,11 +156,11 @@ enum lfs_type {
#ifdef LFS_CKPROGS
#define LFS_F_CKPROGS 0x00100000 // Check progs by reading back progged data
#endif
#ifdef LFS_CKREADS
#define LFS_F_CKREADS 0x00200000 // Check reads via parity bits/checksums
#endif
#ifdef LFS_CKFETCHES
#define LFS_F_CKFETCHES 0x00400000 // Check checksums before reads
#define LFS_F_CKFETCHES 0x00200000 // Check block checksums before first use
#endif
#ifdef LFS_CKPARITY
#define LFS_F_CKPARITY 0x00400000 // Check tag parity bits on reads
#endif
#define LFS_F_MTREEONLY 0x00000800 // Only traverse the mtree
@@ -176,11 +176,11 @@ enum lfs_type {
#ifdef LFS_CKPROGS
#define LFS_M_CKPROGS 0x00100000 // Check progs by reading back progged data
#endif
#ifdef LFS_CKREADS
#define LFS_M_CKREADS 0x00200000 // Check reads via parity bits/checksums
#endif
#ifdef LFS_CKFETCHES
#define LFS_M_CKFETCHES 0x00400000 // Check checksums before reads
#define LFS_M_CKFETCHES 0x00200000 // Check block checksums before first use
#endif
#ifdef LFS_CKPARITY
#define LFS_M_CKPARITY 0x00400000 // Check tag parity bits on reads
#endif
#define LFS_M_MTREEONLY 0x00000800 // Only traverse the mtree
@@ -198,11 +198,11 @@ enum lfs_type {
#ifdef LFS_CKPROGS
#define LFS_I_CKPROGS 0x00100000 // Filesystem mounted with LFS_M_CKPROGS
#endif
#ifdef LFS_CKREADS
#define LFS_I_CKREADS 0x00200000 // Filesystem mounted with LFS_M_CKREADS
#endif
#ifdef LFS_CKFETCHES
#define LFS_I_CKFETCHES 0x00400000 // Filesystem mounted with LFS_M_CKFETCHES
#define LFS_I_CKFETCHES 0x00200000 // Filesystem mounted with LFS_M_CKFETCHES
#endif
#ifdef LFS_CKPARITY
#define LFS_I_CKPARITY 0x00400000 // Filesystem mounted with LFS_M_CKPARITY
#endif
#define LFS_I_INCONSISTENT \
@@ -559,7 +559,7 @@ typedef struct lfsr_omdir {
// lfs_block_t tail[2];
//} lfs_mdir_t;
#ifdef LFS_CKREADS
#ifdef LFS_CKPARITY
// context for validating data
typedef struct lfsr_ck {
// sign(cksize)=0 => cksum check
@@ -582,7 +582,7 @@ typedef struct lfsr_data {
struct {
lfs_block_t block;
lfs_size_t off;
#ifdef LFS_CKREADS
#ifdef LFS_CKPARITY
lfsr_ck_t ck;
#endif
} disk;
@@ -615,7 +615,7 @@ typedef lfsr_data_t lfsr_sprout_t;
typedef struct lfsr_bptr {
lfsr_data_t data;
#ifndef LFS_CKREADS
#ifndef LFS_CKPARITY
lfs_size_t cksize;
uint32_t cksum;
#endif
@@ -757,7 +757,7 @@ typedef struct lfsr_grm {
lfsr_smid_t mids[2];
} lfsr_grm_t;
#ifdef LFS_CKREADS
#ifdef LFS_CKPARITY
typedef struct lfsr_tailck {
lfs_block_t ckblock;
// sign(ckoff) => tail parity
@@ -797,7 +797,7 @@ typedef struct lfs {
uint8_t *buffer;
} pcache;
#ifdef LFS_CKREADS
#ifdef LFS_CKPARITY
lfsr_tailck_t tailck;
#endif