Dropped becksums from direct block pointers

Direct block pointers are turning out to be a bit of an awkward file
representation for littlefs. Thanks to shrubs, direct block pointers
really don't offer that much in terms of disk savings.

Direct bptrs save ~40 B:

  direct bptr:     1 attr + 1 bptr
                   40 B   + 24 B             = 64 B
  indirect bshrub: 2 attr + 1 trunk + 1 bptr
                   2*40 B + 10 B    + 24 B   = 114 B
                                           δ = +40 B (+78.1%)

Which is nice, but not really significant on disk. Their original
motivation was to avoid the cost of a btree root node for one block
files. But this can now be avoided with bshrubs, which also generalizes
to other few-block files.

I can see the argument for carving out a special case for entirely
inlined files. +~40B may be a significant cost there. But I'm just not
seeing the value for bptrs.

But direct bptrs exist as a natural extension of littlefs's design.
Files can have:

1. nothing, null data,
2. a data entry (bptr/bsprout)
3. a bshrub/btree of data entries (bptr/bsprout)

Prohibiting direct bptrs, would be a bit strange, and a future version
of littlefs may find direct bptrs useful. Say, for example, a version
that doesn't support bshrubs, suddenly bptrs become more valuable.

So this is a compromise:

1. Support reading of bptrs, this is not that much extra work on top of
   supporting bsprouts. Though we do need to be aware of them in the
   block allocator.

2. Convert bptrs to bshrubs/btrees on first write.

3. Ignore any extra bptr metadata, becksums, cids, etc. These add an
   additional attr which complicates things.

Downside: We may lose out on potential erased-state when writing to
files created on a different device that uses bptrs. Upside: Simpler
code and a bit of code savings.

            code          stack
  before:  33260           3024
  after:   33136 (-0.4%)   3000 (-0.8%)

Ok, maybe not that much code savings...
This commit is contained in:
Christopher Haster
2024-01-09 12:06:18 -06:00
parent b0bd026b87
commit 7d8315a598
2 changed files with 29 additions and 60 deletions
+2 -8
View File
@@ -511,12 +511,6 @@ typedef struct lfsr_bptr {
uint32_t cksum;
} lfsr_bptr_t;
// a bleaf is just a bptr with all optional attrs
typedef struct lfsr_bleaf {
lfsr_bptr_t bptr;
lfsr_ecksum_t becksum;
} lfsr_bleaf_t;
// a shrub is a secondary trunk in an mdir, we really only need
// trunk/weight/block, so we sneak our estimate into some
// overlapping fields
@@ -540,14 +534,14 @@ typedef struct lfsr_ftree {
//
// sign(size)=1, data.size==0 => bnull
// sign(size)=1, data.block==mdir.block => bsprout
// sign(size)=1, data.block!=mdir.block => bleaf
// sign(size)=1, data.block!=mdir.block => bptr
// sign(size)=0, data.block==mdir.block => bshrub
// sign(size)=0, data.block!=mdir.block => btree
//
union {
lfs_soff_t size;
lfsr_data_t bsprout;
lfsr_bleaf_t bleaf;
lfsr_bptr_t bptr;
lfsr_shrub_t bshrub;
lfsr_btree_t btree;
} u, u_;