Tweaked lfsr_mdir_compact_ to make source rbyd optional

This allows lfsr_mdir_compact_ to also cover the mroot extension commit.

The mroot located at 0x{0,1} is a bit unique in that it can never
relocated. Instead we "extend" the mroot chain by an additional mroot
that can relocate.

One nice thing is we can implement this by letting lfsr_mdir_commit_
perform a normal relocation, and then rewrite the 0x{0,1} mroot with
a pointer to the "relocated" mroot.

Though we have to take extra care to make sure this write doesn't
recursively trigger an additional relocate, which would never terminate.

Fortunately, this situation only happens when we are compacting the
0x{0,1} mroot. Which simplifies things a bit.
This commit is contained in:
Christopher Haster
2023-05-14 14:59:34 -05:00
parent 395eff49ad
commit 7b1c35a99b
+13 -26
View File
@@ -4635,11 +4635,13 @@ static int lfsr_mdir_compact_(lfs_t *lfs, lfsr_mdir_t *mdir,
}
// copy over attrs
err = lfsr_rbyd_compact(lfs, &mdir->rbyd, start_id, end_id, false,
&source->rbyd);
if (err) {
LFS_ASSERT(err != LFS_ERR_RANGE);
return err;
if (source) {
err = lfsr_rbyd_compact(lfs, &mdir->rbyd, start_id, end_id, false,
&source->rbyd);
if (err) {
LFS_ASSERT(err != LFS_ERR_RANGE);
return err;
}
}
// append any pending attrs
@@ -5312,28 +5314,13 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, lfs_ssize_t *rid,
return d;
}
// TODO should this swap be an mdir function?
// compact into new mparentroot
lfsr_mdir_t mparentroot_ = mchildroot;
// swap our rbyds
lfs_swap32(&mparentroot_.rbyd.block, &mparentroot_.other_block);
// update our revision count
// TODO rev things
mparentroot_.rbyd.rev += 1;
mparentroot_.rbyd.off = 0;
mparentroot_.rbyd.trunk = 0;
mparentroot_.rbyd.weight = 0;
mparentroot_.rbyd.crc = 0;
// erase, preparing for compact
err = lfsr_bd_erase(lfs, mparentroot_.rbyd.block);
if (err) {
return err;
}
err = lfsr_rbyd_commit(lfs, &mparentroot_.rbyd, LFSR_ATTRS(
LFSR_ATTR_DATA(-1, MAGIC, 0, magic),
LFSR_ATTR_DATA(-1, CONFIG, 0, config),
LFSR_ATTR(-1, MROOT, 0, buf, d)));
err = lfsr_mdir_compact_(lfs, &mparentroot_, -1, -1,
NULL, NULL, 0, LFSR_ATTRS(
LFSR_ATTR_DATA(-1, MAGIC, 0, magic),
LFSR_ATTR_DATA(-1, CONFIG, 0, config),
LFSR_ATTR(-1, MROOT, 0, buf, d)));
if (err) {
return err;
}