From 7b1c35a99bca7c9a6f2539ffde73ff3a0b3da61d Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Sun, 14 May 2023 14:59:34 -0500 Subject: [PATCH] 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. --- lfs.c | 39 +++++++++++++-------------------------- 1 file changed, 13 insertions(+), 26 deletions(-) diff --git a/lfs.c b/lfs.c index b9919017..bdc4671a 100644 --- a/lfs.c +++ b/lfs.c @@ -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; }