Added more file tests with multiple files, fixed bugs

Fortunately these operations are heavily tested in test_dirs. The only
difference with files is the possibility for shrubs to need to be
copied.

Bugs fixed:

- It's counterintuitive, but lfsr_rbyd_appendcompactattr _can_ error
  with LFS_ERR_RANGE when we are copying a shrub. This can happen if the
  underlying mdir needs compaction itself.

- It's possible to null-trunk bshrubs to appear in our filesystem
  traversal. Null-trunk bshrubs don't usually appear in any stable
  state, but they are created by lfsr_bshrub_alloc and lfsr_btree_commit
  to represent new, yet-uncommitted shrubs.

  This gets a bit tricky because we also use null-trunks to indicate if
  lfsr_btree_traversal has traversed the root. We can't rely on
  bid >= weight for this because zero-weight btrees are allowed.

  The solution here, though maybe temporary (famous last words), is to
  treat null-trunk btrees as not having a root. Which isn't really true,
  but null-trunk btree roots only exist between allocator checkpoints,
  so they are allowed to be unreachable.

  We really need more asserts that this is the case though... At least
  added an assert that we never commit/read null trunks on disk.
This commit is contained in:
Christopher Haster
2023-12-01 15:58:44 -06:00
parent 939dd2145a
commit 6261bafed2
2 changed files with 1069 additions and 15 deletions
+7 -5
View File
@@ -1862,6 +1862,8 @@ static int lfsr_data_readgrm(lfs_t *lfs, lfsr_data_t *data,
static lfsr_data_t lfsr_data_fromtrunk(lfs_size_t trunk, lfsr_rid_t weight,
uint8_t buffer[static LFSR_TRUNK_DSIZE]) {
// shrub trunks should never be null
LFS_ASSERT(trunk != 0);
lfs_ssize_t d = 0;
// just write the trunk and weight, the rest of the rbyd is contextual
@@ -1890,6 +1892,8 @@ static int lfsr_data_readtrunk(lfs_t *lfs, lfsr_data_t *data,
return err;
}
// shrub trunks should never be null
LFS_ASSERT(*trunk != 0);
return 0;
}
@@ -3267,7 +3271,6 @@ static int lfsr_rbyd_appendcompactrbyd(lfs_t *lfs, lfsr_rbyd_t *rbyd_,
err = lfsr_rbyd_appendcompactattr(lfs, rbyd_,
((shrub) ? LFSR_TAG_SHRUB : 0) | tag, weight, data);
if (err) {
LFS_ASSERT(err != LFS_ERR_RANGE);
return err;
}
}
@@ -4608,14 +4611,13 @@ typedef struct lfsr_binfo {
static int lfsr_btree_traverse(lfs_t *lfs, const lfsr_btree_t *btree,
lfsr_btraversal_t *btraversal,
lfsr_binfo_t *binfo) {
// this shouldn't happen
LFS_ASSERT(btree->trunk != 0);
while (true) {
// in range?
if (btraversal->bid >= (lfsr_bid_t)btree->weight
// make sure we traverse the root even if weight=0
&& btraversal->branch.trunk != 0) {
&& (btraversal->branch.trunk != 0
// unless we don't even have a root yet
|| btree->trunk == 0)) {
return LFS_ERR_NOENT;
}
+1062 -10
View File
File diff suppressed because it is too large Load Diff