trv: Fixed issue with not clobbering mroot chain mdirs
This was introduced with the simplified traversal clobbering logic.
Previously, traversal clobbering was a bit more aggressive, relying on
the explicit tstate state machine. This was replaced by implicit
mid-related state, which looks like it may have introduced some holes.
In this case, lfs3_mdir_commit was failing to clobber non-active mroot
chain mdirs. Non-active mroots are particularly tricky because we
(1) don't track these in-RAM, (2) only reach them during traversals,
and (3) require heavy wear-leveling writes for them to even appear in
in system.
---
The solution here is an extra check in lfs3_mdir_commit_'s post-commit
state updates to update any mid<=-1 mroots to the new active mroot.
This clobbers mroot chain traversals by skipping non-active mroots, but
this is unavoidable since lfs3_mdir_commit_ could always introduce
new/relocate mroot chain mroots. Note this should match the previous
state-machine dependent behavior.
Code changes:
code stack ctx
before: 35144 2136 660
after: 35152 (+0.0%) 2136 (+0.0%) 660 (+0.0%)
code stack ctx
gbmap before: 38380 2144 776
gbmap after: 38392 (+0.0%) 2144 (+0.0%) 776 (+0.0%)
code stack ctx
preerase before: 38920 2168 796
preerase after: 38928 (+0.0%) 2168 (+0.0%) 796 (+0.0%)
This commit is contained in:
@@ -9371,6 +9371,9 @@ static int lfs3_mdir_commit_(lfs3_t *lfs3, lfs3_mdir_t *mdir,
|
|||||||
}
|
}
|
||||||
} else if (h->mdir.mid > mdir->mid) {
|
} else if (h->mdir.mid > mdir->mid) {
|
||||||
h->mdir.mid += mdelta;
|
h->mdir.mid += mdelta;
|
||||||
|
// and any mroot updates, though this clobbers chain mroots
|
||||||
|
} else if (h->mdir.mid <= -1) {
|
||||||
|
lfs3_mdir_sync(&h->mdir, &mroot_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+9
-10
@@ -4103,6 +4103,9 @@ code = '''
|
|||||||
assert(tinfo.btype == LFS3_BTYPE_BTREE);
|
assert(tinfo.btype == LFS3_BTYPE_BTREE);
|
||||||
assert(tinfo.block == 2);
|
assert(tinfo.block == 2);
|
||||||
}
|
}
|
||||||
|
// traverse mtree
|
||||||
|
lfs3_trv_read(&lfs3, &trv, &tinfo) => 0;
|
||||||
|
assert(tinfo.btype == LFS3_BTYPE_BTREE);
|
||||||
// traverse mdir
|
// traverse mdir
|
||||||
lfs3_trv_read(&lfs3, &trv, &tinfo) => 0;
|
lfs3_trv_read(&lfs3, &trv, &tinfo) => 0;
|
||||||
assert(tinfo.btype == LFS3_BTYPE_MDIR);
|
assert(tinfo.btype == LFS3_BTYPE_MDIR);
|
||||||
@@ -4762,11 +4765,6 @@ code = '''
|
|||||||
// still traverse inlined mroots, so if this breaks in the future
|
// still traverse inlined mroots, so if this breaks in the future
|
||||||
// I wouldn't worry too much about it
|
// I wouldn't worry too much about it
|
||||||
//
|
//
|
||||||
// traverse an mdir
|
|
||||||
lfs3_trv_read(&lfs3, &trv, &tinfo) => 0;
|
|
||||||
assert(tinfo.btype == LFS3_BTYPE_MDIR);
|
|
||||||
lfs3_trv_read(&lfs3, &trv, &tinfo) => 0;
|
|
||||||
assert(tinfo.btype == LFS3_BTYPE_MDIR);
|
|
||||||
// traverse gbmap
|
// traverse gbmap
|
||||||
if (GBMAP) {
|
if (GBMAP) {
|
||||||
lfs3_trv_read(&lfs3, &trv, &tinfo) => 0;
|
lfs3_trv_read(&lfs3, &trv, &tinfo) => 0;
|
||||||
@@ -6078,11 +6076,6 @@ code = '''
|
|||||||
lfs3_trv_close(&lfs3, &trv) => 0;
|
lfs3_trv_close(&lfs3, &trv) => 0;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
// traverse mdir
|
|
||||||
lfs3_trv_read(&lfs3, &trv, &tinfo) => 0;
|
|
||||||
assert(tinfo.btype == LFS3_BTYPE_MDIR);
|
|
||||||
lfs3_trv_read(&lfs3, &trv, &tinfo) => 0;
|
|
||||||
assert(tinfo.btype == LFS3_BTYPE_MDIR);
|
|
||||||
// traverse mtree
|
// traverse mtree
|
||||||
lfs3_trv_read(&lfs3, &trv, &tinfo) => 0;
|
lfs3_trv_read(&lfs3, &trv, &tinfo) => 0;
|
||||||
assert(tinfo.btype == LFS3_BTYPE_BTREE);
|
assert(tinfo.btype == LFS3_BTYPE_BTREE);
|
||||||
@@ -7766,6 +7759,9 @@ code = '''
|
|||||||
assert(tinfo.btype == LFS3_BTYPE_BTREE);
|
assert(tinfo.btype == LFS3_BTYPE_BTREE);
|
||||||
assert(tinfo.block == 2);
|
assert(tinfo.block == 2);
|
||||||
}
|
}
|
||||||
|
// traverse mtree
|
||||||
|
lfs3_trv_read(&lfs3, &trv, &tinfo) => 0;
|
||||||
|
assert(tinfo.btype == LFS3_BTYPE_BTREE);
|
||||||
// traverse mdirs
|
// traverse mdirs
|
||||||
lfs3_trv_read(&lfs3, &trv, &tinfo) => 0;
|
lfs3_trv_read(&lfs3, &trv, &tinfo) => 0;
|
||||||
assert(tinfo.btype == LFS3_BTYPE_MDIR);
|
assert(tinfo.btype == LFS3_BTYPE_MDIR);
|
||||||
@@ -8946,6 +8942,9 @@ code = '''
|
|||||||
assert(tinfo.btype == LFS3_BTYPE_BTREE);
|
assert(tinfo.btype == LFS3_BTYPE_BTREE);
|
||||||
assert(tinfo.block == 2);
|
assert(tinfo.block == 2);
|
||||||
}
|
}
|
||||||
|
// traverse mtree
|
||||||
|
lfs3_trv_read(&lfs3, &trv, &tinfo) => 0;
|
||||||
|
assert(tinfo.btype == LFS3_BTYPE_BTREE);
|
||||||
// traverse mdirs
|
// traverse mdirs
|
||||||
lfs3_trv_read(&lfs3, &trv, &tinfo) => 0;
|
lfs3_trv_read(&lfs3, &trv, &tinfo) => 0;
|
||||||
assert(tinfo.btype == LFS3_BTYPE_MDIR);
|
assert(tinfo.btype == LFS3_BTYPE_MDIR);
|
||||||
|
|||||||
Reference in New Issue
Block a user