Fixed mroot commit conditions that relied on mdelta==0
This was broken. The good news is this was easily detected by our
test_mtree tests.
The problem is that mroot split + drop (resulting in an mtree with one
mdir) is indistinguishable from mroot relocation via mdelta. Both cases
have an mdelta of 0.
This also breaks the later mid-mdir update if we wanted to stay on the
current chain mroot.
The tricky part is we have several entangled cases:
- mdir=active mroot, mid>=0 - follow mdir_
- mdir=active mroot, mid<=-1 - follow mroot_, not mdir_!
- mdir=chain mroot, mid<=-1 - follow mdir_, not mroot_!
---
It's tempting to rely on mid<=-2 vs mid==-1 for chain mroots vs active
mroot, but this doesn't always work! During traversals mid is always
<=-2, in part because we don't actually know if the current mroot is the
active mroot until we try to lookup its child.
Fortunately, what _does_ work is just comparing against the mroot's
blocks, which we know.
Though the continued reliance and reliability of mptr comparisons makes
me wonder if it's possible to simplify said function...
Code changes:
code stack ctx
before: 35224 2136 660
after: 35260 (+0.1%) 2136 (+0.0%) 660 (+0.0%)
code stack ctx
gbmap before: 38464 2144 776
gbmap after: 38492 (+0.1%) 2144 (+0.0%) 776 (+0.0%)
code stack ctx
preerase before: 39008 2168 796
preerase after: 39036 (+0.1%) 2168 (+0.0%) 796 (+0.0%)
This commit is contained in:
@@ -9232,7 +9232,7 @@ static int lfs3_mdir_commit_(lfs3_t *lfs3, lfs3_mdir_t *mdir,
|
||||
|
||||
// need to update mroot chain?
|
||||
if (lfs3_mdir_cmp(&mroot_, &lfs3->mroot) != 0
|
||||
|| (mdelta == 0 && mdir->mid <= -1)) {
|
||||
|| (mdir->mid <= -1 && lfs3_mdir_cmp(mdir, &lfs3->mroot) != 0)) {
|
||||
// tail recurse, updating mroots until a commit sticks
|
||||
lfs3_mdir_t mrootchild;
|
||||
lfs3_mdir_t mrootchild_;
|
||||
@@ -9399,8 +9399,7 @@ static int lfs3_mdir_commit_(lfs3_t *lfs3, lfs3_mdir_t *mdir,
|
||||
}
|
||||
|
||||
// update mdir to follow requested rid
|
||||
if (mdelta > 0
|
||||
&& mdir->mid <= -1) {
|
||||
if (mdir->mid <= -1 && lfs3_mdir_cmp(mdir, &lfs3->mroot) == 0) {
|
||||
lfs3_mdir_sync(mdir, &mroot_);
|
||||
} else if (mdelta > 0
|
||||
&& lfs3_mrid(lfs3, mdir->mid)
|
||||
|
||||
Reference in New Issue
Block a user