Added bigger_than_expected tests, allow fragments/blocks > weight

This may be useful for compression in the future, where compression +
noise can result in blocks _larger_ than the expected weight.

Thinking about how compression might be integrated into littlefs, it
would be nice if such a topology did _not_ trigger asserts. This would
allow littlefs images to interact with compressed files at least a
little bit (rename/remove could be very useful), even if the compression
algorithm isn't supported.

Supporting this requires only a single clamp in lfsr_file_lookupleaf,
but it's a little bit more costly than you might expect:

           code          stack          ctx
  before: 35692           2440          640
  after:  35740 (+0.1%)   2440 (+0.0%)  640 (+0.0%)

This is due to internal API awkwardness:

1. LFSR_DATA_TRUNCATE is surprisingly costly
2. We need to create a local weight copy in case the caller's is NULL
This commit is contained in:
Christopher Haster
2025-04-21 20:21:22 -05:00
parent a0b3eccf15
commit 0a485da7c9
2 changed files with 231 additions and 2 deletions
+10 -2
View File
@@ -11505,17 +11505,21 @@ static int lfsr_file_lookupleaf(lfs_t *lfs, const lfsr_file_t *file,
lfsr_bid_t *bid_, lfsr_rbyd_t *rbyd_, lfsr_srid_t *rid_,
lfsr_bid_t *weight_, lfsr_bptr_t *bptr_) {
lfsr_tag_t tag;
lfsr_bid_t weight;
lfsr_data_t data;
int err = lfsr_bshrub_lookupleaf(lfs, &file->b, bid,
bid_, rbyd_, rid_, &tag, weight_, &data);
bid_, rbyd_, rid_, &tag, &weight, &data);
if (err) {
return err;
}
LFS_ASSERT(tag == LFSR_TAG_DATA
|| tag == LFSR_TAG_BLOCK);
// decode bptrs
if (weight_) {
*weight_ = weight;
}
if (bptr_) {
// decode bptrs
if (tag == LFSR_TAG_DATA) {
bptr_->data = data;
} else {
@@ -11524,6 +11528,10 @@ static int lfsr_file_lookupleaf(lfs_t *lfs, const lfsr_file_t *file,
return err;
}
}
// limit bptrs to btree weights, this may be useful for
// compression in the future
bptr_->data = LFSR_DATA_TRUNCATE(bptr_->data, weight);
}
return 0;
}