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:
@@ -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_;
|
||||
|
||||
Reference in New Issue
Block a user