diff --git a/lfs.c b/lfs.c index 09e4dd45..64cd0138 100644 --- a/lfs.c +++ b/lfs.c @@ -5248,10 +5248,12 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, return err; } - LFS_DEBUG("Splitting mdir %"PRId32" 0x{%"PRIx32",%"PRIx32"} " - "-> 0x{%"PRIx32",%"PRIx32"}" - ", 0x{%"PRIx32",%"PRIx32"}", - mdir->mid, + LFS_DEBUG("Splitting mdir %"PRId32".%"PRId32" " + "0x{%"PRIx32",%"PRIx32"} " + "-> 0x{%"PRIx32",%"PRIx32"}, " + "0x{%"PRIx32",%"PRIx32"}", + mdir->mid & lfsr_mbidmask(lfs), + mdir->mid & lfsr_mridmask(lfs), mdir->u.m.blocks[0], mdir->u.m.blocks[1], mdir_.u.m.blocks[0], mdir_.u.m.blocks[1], msibling_.u.m.blocks[0], msibling_.u.m.blocks[1]); @@ -5261,11 +5263,15 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, // both siblings reduced to zero if (mdir_.u.m.weight == 0 && msibling_.u.m.weight == 0) { - LFS_DEBUG("Dropping mdir %"PRId32" 0x{%"PRIx32",%"PRIx32"}", - mdir_.mid, + LFS_DEBUG("Dropping mdir %"PRId32".%"PRId32" " + "0x{%"PRIx32",%"PRIx32"}", + mdir_.mid & lfsr_mbidmask(lfs), + mdir_.mid & lfsr_mridmask(lfs), mdir_.u.m.blocks[0], mdir_.u.m.blocks[1]); - LFS_DEBUG("Dropping mdir %"PRId32" 0x{%"PRIx32",%"PRIx32"}", - msibling_.mid, + LFS_DEBUG("Dropping mdir %"PRId32".%"PRId32" " + "0x{%"PRIx32",%"PRIx32"}", + msibling_.mid & lfsr_mbidmask(lfs), + msibling_.mid & lfsr_mridmask(lfs), msibling_.u.m.blocks[0], msibling_.u.m.blocks[1]); // mark as dropped mdir_.u.r.rbyd.trunk = 0; @@ -5281,8 +5287,10 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, // one sibling reduced to zero } else if (msibling_.u.m.weight == 0) { - LFS_DEBUG("Dropping mdir %"PRId32" 0x{%"PRIx32",%"PRIx32"}", - msibling_.mid, + LFS_DEBUG("Dropping mdir %"PRId32".%"PRId32" " + "0x{%"PRIx32",%"PRIx32"}", + msibling_.mid & lfsr_mbidmask(lfs), + msibling_.mid & lfsr_mridmask(lfs), msibling_.u.m.blocks[0], msibling_.u.m.blocks[1]); // mark as dropped @@ -5305,8 +5313,10 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, // other sibling reduced to zero } else if (mdir_.u.m.weight == 0) { - LFS_DEBUG("Dropping mdir %"PRId32" 0x{%"PRIx32",%"PRIx32"}", - mdir_.mid, + LFS_DEBUG("Dropping mdir %"PRId32".%"PRId32" " + "0x{%"PRIx32",%"PRIx32"}", + mdir_.mid & lfsr_mbidmask(lfs), + mdir_.mid & lfsr_mridmask(lfs), mdir_.u.m.blocks[0], mdir_.u.m.blocks[1]); // mark as dropped @@ -5379,8 +5389,10 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, } else if (mdir_.u.m.weight == 0 // unless we are an mroot && !(mdir->mid == -1 || lfsr_mtree_isinlined(lfs))) { - LFS_DEBUG("Dropping mdir %"PRId32" 0x{%"PRIx32",%"PRIx32"}", - mdir->mid, + LFS_DEBUG("Dropping mdir %"PRId32".%"PRId32" " + "0x{%"PRIx32",%"PRIx32"}", + mdir->mid & lfsr_mbidmask(lfs), + mdir->mid & lfsr_mridmask(lfs), mdir->u.m.blocks[0], mdir->u.m.blocks[1]); // mark as dropped @@ -5406,9 +5418,10 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir, // relocate a normal mdir } else { - LFS_DEBUG("Relocating mdir %"PRId32" 0x{%"PRIx32",%"PRIx32"} " - "-> 0x{%"PRIx32",%"PRIx32"}", - mdir->mid, + LFS_DEBUG("Relocating mdir %"PRId32".%"PRId32" " + "0x{%"PRIx32",%"PRIx32"} -> 0x{%"PRIx32",%"PRIx32"}", + mdir->mid & lfsr_mbidmask(lfs), + mdir->mid & lfsr_mridmask(lfs), mdir->u.m.blocks[0], mdir->u.m.blocks[1], mdir_.u.m.blocks[0], mdir_.u.m.blocks[1]); @@ -6564,9 +6577,18 @@ static int lfsr_mountinited(lfs_t *lfs) { } if (lfsr_grm_hasrm(&lfs->grm)) { - LFS_DEBUG("Found pending grm %"PRId32" %"PRId32, - lfs->grm.rms[0], - lfs->grm.rms[1]); + if (lfsr_grm_count(&lfs->grm) == 2) { + LFS_DEBUG("Found pending grm " + "%"PRId32".%"PRId32" %"PRId32".%"PRId32, + lfs->grm.rms[0] & lfsr_mbidmask(lfs), + lfs->grm.rms[0] & lfsr_mridmask(lfs), + lfs->grm.rms[0] & lfsr_mbidmask(lfs), + lfs->grm.rms[0] & lfsr_mridmask(lfs)); + } else if (lfsr_grm_count(&lfs->grm) == 1) { + LFS_DEBUG("Found pending grm %"PRId32".%"PRId32, + lfs->grm.rms[0] & lfsr_mbidmask(lfs), + lfs->grm.rms[0] & lfsr_mridmask(lfs)); + } } return 0; @@ -7380,9 +7402,18 @@ static int lfsr_fs_preparemutation(lfs_t *lfs) { // fix pending grms if (lfsr_grm_hasrm(&lfs->grm)) { - LFS_DEBUG("Fixing grm %"PRId32" %"PRId32, - lfs->grm.rms[0], - lfs->grm.rms[1]); + if (lfsr_grm_count(&lfs->grm) == 2) { + LFS_DEBUG("Fixing pending grm " + "%"PRId32".%"PRId32" %"PRId32".%"PRId32, + lfs->grm.rms[0] & lfsr_mbidmask(lfs), + lfs->grm.rms[0] & lfsr_mridmask(lfs), + lfs->grm.rms[0] & lfsr_mbidmask(lfs), + lfs->grm.rms[0] & lfsr_mridmask(lfs)); + } else if (lfsr_grm_count(&lfs->grm) == 1) { + LFS_DEBUG("Fixing pending grm %"PRId32".%"PRId32, + lfs->grm.rms[0] & lfsr_mbidmask(lfs), + lfs->grm.rms[0] & lfsr_mridmask(lfs)); + } int err = lfsr_fs_fixgrm(lfs); if (err) { diff --git a/scripts/dbgbtree.py b/scripts/dbgbtree.py index c1f80a40..109cf35a 100755 --- a/scripts/dbgbtree.py +++ b/scripts/dbgbtree.py @@ -812,7 +812,7 @@ def main(disk, roots=None, *, print('%-9s %*s%-*s %-22s %s' % ( 'rbyd', t_width, '', - w_width, 'ids', + w_width, 'bid', 'tag', 'data (truncated)' if not args.get('no_truncate') else '')) diff --git a/scripts/dbglfs.py b/scripts/dbglfs.py index 1b753093..ea505814 100755 --- a/scripts/dbglfs.py +++ b/scripts/dbglfs.py @@ -454,7 +454,7 @@ class Rbyd: return not tags, bid + (rid_-rid), w, rbyd, rid_, tags, path # mtree lookup with this rbyd as the mroot - def mtree_lookup(self, f, block_size, mid): + def mtree_lookup(self, f, block_size, mbid): # have mtree? done, rid, tag, w, j, d, data, _ = self.lookup(-1, TAG_MTREE) if not done and rid == -1 and tag == TAG_MTREE: @@ -462,39 +462,39 @@ class Rbyd: mtree = Rbyd.fetch(f, block_size, block, trunk) # corrupted? if not mtree: - return None + return True, -1, 0, None - # lookup our mid - done, mid, w, rbyd, rid, tags, path = mtree.btree_lookup( - f, block_size, mid) + # lookup our mbid + done, mbid, mw, rbyd, rid, tags, path = mtree.btree_lookup( + f, block_size, mbid) if done: - return None + return True, -1, 0, None mdir = next(((tag, j, d, data) for tag, j, d, data in tags if tag == TAG_MDIR), None) if not mdir: - return None + return True, -1, 0, None # fetch the mdir _, _, _, data = mdir blocks = frommdir(data) - return Rbyd.fetch(f, block_size, blocks) + return False, mbid, mw, Rbyd.fetch(f, block_size, blocks) else: # have mdir? done, rid, tag, w, j, _, data, _ = self.lookup(-1, TAG_MDIR) if not done and rid == -1 and tag == TAG_MDIR: blocks = frommdir(data) - return Rbyd.fetch(f, block_size, blocks) + return False, 0, 0, Rbyd.fetch(f, block_size, blocks) else: # I guess we're inlined? - if mid == -1: - return self + if mbid == -1: + return False, -1, 0, self else: - return None + return True, -1, 0, None # lookup by name def namelookup(self, did, name): @@ -564,7 +564,7 @@ class Rbyd: return False, -1, None, -1, 0, 0 # lookup our name in the mtree - mid, tag_, w, data = mtree.btree_namelookup( + mbid, tag_, mw, data = mtree.btree_namelookup( f, block_size, did, name) if tag_ != TAG_MDIR: return False, -1, None, -1, 0, 0 @@ -578,22 +578,24 @@ class Rbyd: done, rid, tag, w, j, _, data, _ = self.lookup(-1, TAG_MDIR) if not done and rid == -1 and tag == TAG_MDIR: blocks = frommdir(data) - mid = 0 + mbid = 0 + mw = 0 mdir = Rbyd.fetch(f, block_size, blocks) else: # I guess we're inlined? - mid = -1 + mbid = -1 + mw = 0 mdir = self # lookup name in our mdir found, rid, tag, w = mdir.namelookup(did, name) - return found, mid, mdir, rid, tag, w + return found, mbid, mw, mdir, rid, tag, w # iterate through a directory assuming this is the mtree root def mtree_dir(self, f, block_size, did): # lookup the bookmark - found, mid, mdir, rid, tag, w = self.mtree_namelookup( + found, mbid, mw, mdir, rid, tag, w = self.mtree_namelookup( f, block_size, did, b'') # iterate through all files until the next bookmark while found: @@ -611,15 +613,15 @@ class Rbyd: break # yield what we've found - yield name_, mid, mdir, rid, tag, w + yield name_, mbid, mw, mdir, rid, tag, w rid += w if rid >= mdir.weight: rid -= mdir.weight - mid += 1 + mbid += 1 - mdir = self.mtree_lookup(f, block_size, mid) - if not mdir: + done, mbid, mw, mdir = self.mtree_lookup(f, block_size, mbid) + if done: break @@ -651,11 +653,12 @@ def superconfig(mroot): # collect gstate class GState: - def __init__(self): + def __init__(self, block_size): self.gstate = {} self.gdelta = {} + self.block_size = block_size - def xor(self, mid, mdir): + def xor(self, mbid, mw, mdir): tag = TAG_GSTATE-0x1 while True: done, rid, tag, w, j, d, data, _ = mdir.lookup(-1, tag+0x1) @@ -665,7 +668,7 @@ class GState: # keep track of gdeltas if tag not in self.gdelta: self.gdelta[tag] = [] - self.gdelta[tag].append((mid, mdir, j, d, data)) + self.gdelta[tag].append((mbid, mw, mdir, j, d, data)) # xor gstate if tag not in self.gstate: @@ -679,6 +682,10 @@ class GState: if TAG_GRM not in self.gstate: return [] + # derive the mbid/mrid masks from the block_size + mridmask = (1 << m.ceil(m.log2(self.block_size // 16)))-1 + mbidmask = ~mridmask + data = self.gstate[TAG_GRM] d = 0 count, d_ = fromleb128(data[d:]); d += d_ @@ -686,23 +693,25 @@ class GState: if count <= 2: for _ in range(count): mid, d_ = fromleb128(data[d:]); d += d_ - rid, d_ = fromleb128(data[d:]); d += d_ - rms.append((mid, rid)) + rms.append((mid & mbidmask, mid & mridmask)) return rms -def grepr(tag, data): +def grepr(tag, data, block_size): if tag == TAG_GRM: + # derive the mbid/mrid masks from the block_size + mridmask = (1 << m.ceil(m.log2(block_size // 16)))-1 + mbidmask = ~mridmask + d = 0 count, d_ = fromleb128(data[d:]); d += d_ rms = [] if count <= 2: for _ in range(count): mid, d_ = fromleb128(data[d:]); d += d_ - rid, d_ = fromleb128(data[d:]); d += d_ - rms.append((mid, rid)) + rms.append((mid & mbidmask, mid & mridmask)) return 'grm %s' % ( 'none' if count == 0 - else ' '.join('%d.%d' % (mid, rid) for mid, rid in rms) + else ' '.join('%d.%d' % (mbid, rid) for mbid, rid in rms) if count <= 2 else '0x%x' % count) else: @@ -763,9 +772,9 @@ def main(disk, mroots=None, *, mweight = 0 rweight = 0 corrupted = False - gstate = GState() + gstate = GState(block_size) config = {} - dir_dids = [(0, b'', -1, None, -1, TAG_DID, 0)] + dir_dids = [(0, b'', -1, 0, None, -1, TAG_DID, 0)] bookmark_dids = [] mroot = Rbyd.fetch(f, block_size, mroots) @@ -778,7 +787,7 @@ def main(disk, mroots=None, *, rweight = max(rweight, mroot.weight) # yes we get gstate from all mroots - gstate.xor(-1, mroot) + gstate.xor(-1, 0, mroot) # get the superconfig config = superconfig(mroot) @@ -787,11 +796,11 @@ def main(disk, mroots=None, *, if tag == TAG_DID: did, d = fromleb128(data) dir_dids.append( - (did, data[d:], -1, mroot, rid, tag, w)) + (did, data[d:], -1, 0, mroot, rid, tag, w)) elif tag == TAG_BOOKMARK: did, d = fromleb128(data) bookmark_dids.append( - (did, data[d:], -1, mroot, rid, tag, w)) + (did, data[d:], -1, 0, mroot, rid, tag, w)) # fetch the next mroot done, rid, tag, w, j, d, data, _ = mroot.lookup(-1, TAG_MROOT) @@ -821,11 +830,11 @@ def main(disk, mroots=None, *, if tag == TAG_DID: did, d = fromleb128(data) dir_dids.append(( - did, data[d:], 0, mdir, rid, tag, w)) + did, data[d:], 0, 0, mdir, rid, tag, w)) elif tag == TAG_BOOKMARK: did, d = fromleb128(data) bookmark_dids.append(( - did, data[d:], 0, mdir, rid, tag, w)) + did, data[d:], 0, 0, mdir, rid, tag, w)) # fetch the actual mtree, if there is one mtree = None @@ -837,10 +846,10 @@ def main(disk, mroots=None, *, mweight = w # traverse entries - mid = -1 + mbid = -1 while True: - done, mid, w, rbyd, rid, tags, path = mtree.btree_lookup( - f, block_size, mid+1) + done, mbid, mw, rbyd, rid, tags, path = mtree.btree_lookup( + f, block_size, mbid+1) if done: break @@ -865,26 +874,30 @@ def main(disk, mroots=None, *, corrupted = True else: rweight = max(rweight, mdir_.weight) - gstate.xor(mid, mdir_) + gstate.xor(mbid, mw, mdir_) # find any dids for rid, tag, w, j, d, data in mdir_: if tag == TAG_DID: did, d = fromleb128(data) dir_dids.append(( - did, data[d:], mid, mdir_, rid, tag, w)) + did, data[d:], + mbid, mw, mdir_, rid, tag, w)) elif tag == TAG_BOOKMARK: did, d = fromleb128(data) bookmark_dids.append(( - did, data[d:], mid, mdir_, rid, tag, w)) + did, data[d:], + mbid, mw, mdir_, rid, tag, w)) # remove grms from our found dids, we treat these as already deleted grmed_dir_dids = {did_ - for (did_, name_, mid_, mdir_, rid_, tag_, w_) in dir_dids - if (max(mid_, 0), rid_) not in gstate.grm} + for (did_, name_, mbid_, mw_, mdir_, rid_, tag_, w_) + in dir_dids + if (max(mbid_-max(mw_-1, 0), 0), rid_) not in gstate.grm} grmed_bookmark_dids = {did_ - for (did_, name_, mid_, mdir_, rid_, tag_, w_) in bookmark_dids - if (max(mid_, 0), rid_) not in gstate.grm} + for (did_, name_, mbid_, mw_, mdir_, rid_, tag_, w_) + in bookmark_dids + if (max(mbid_-max(mw_-1, 0), 0), rid_) not in gstate.grm} # treat the filesystem as corrupted if our dirs and bookmarks are # mismatched, this should never happen unless there's a bug @@ -902,7 +915,7 @@ def main(disk, mroots=None, *, def rec_f_width(did, depth): depth_ = 0 width_ = 0 - for name, mid, mdir, rid, tag, w in mroot.mtree_dir( + for name, mbid, mw, mdir, rid, tag, w in mroot.mtree_dir( f, block_size, did): width_ = max(width_, len(name)) # recurse? @@ -936,13 +949,13 @@ def main(disk, mroots=None, *, if dtree: print('%-11s %-*s %-*s %s' % ( 'mdir', - w_width, 'ids', + w_width, 'mid', f_width, 'name', 'type')) else: print('%-11s %-*s %-22s %s' % ( 'mdir', - w_width, 'ids', + w_width, 'mid', 'tag', 'data (truncated)' if not args.get('no_truncate') else '')) @@ -985,7 +998,7 @@ def main(disk, mroots=None, *, print('%12s %-*s %s' % ( 'gstate:' if i == 0 else '', w_width + 23, - grepr(tag, data), + grepr(tag, data, block_size), next(xxd(data, 8), '') if not args.get('no_truncate') else '')) @@ -1014,13 +1027,13 @@ def main(disk, mroots=None, *, # print gdeltas? if args.get('gdelta'): - for mid, mdir, j, d, data in gstate.gdelta[tag]: + for mbid, mw, mdir, j, d, data in gstate.gdelta[tag]: print('%s{%s}: %*s %-22s %s%s' % ( '\x1b[90m' if color else '', ','.join('%04x' % block for block in it.chain([mdir.block], mdir.redund_blocks)), - w_width, mid, + w_width, mbid-max(mw-1, 0), tagrepr(tag, 0, len(data)), next(xxd(data, 8), '') if not args.get('no_truncate') else '', @@ -1060,39 +1073,40 @@ def main(disk, mroots=None, *, # print dtree? if dtree: # only show mdir on change - pmid = None + pmbid = None # recursively print directories def rec_dir(did, depth, prefixes=('', '', '', '')): - nonlocal pmid + nonlocal pmbid # collect all entries first so we know when the dir ends dir = [] - for name, mid, mdir, rid, tag, w in mroot.mtree_dir( + for name, mbid, mw, mdir, rid, tag, w in mroot.mtree_dir( f, block_size, did): if not args.get('all'): # skip bookmarks if tag == TAG_BOOKMARK: continue # skip grmed entries - if (max(mid, 0), rid) in gstate.grm: + if (max(mbid-max(mw-1, 0), 0), rid) in gstate.grm: continue - dir.append((name, mid, mdir, rid, tag, w)) + dir.append((name, mbid, mw, mdir, rid, tag, w)) # if we're root, append any orphaned bookmark entries so they # get reported if did == 0: - for did, name, mid, mdir, rid, tag, w in bookmark_dids: + for did, name, mbid, mw, mdir, rid, tag, w in bookmark_dids: if did in grmed_dir_dids: continue # skip grmed entries if (not args.get('all') - and (max(mid, 0), rid) in gstate.grm): + and (max(mbid-max(mw-1, 0), 0), rid) + in gstate.grm): continue - dir.append((name, mid, mdir, rid, tag, w)) + dir.append((name, mbid, mw, mdir, rid, tag, w)) - for i, (name, mid, mdir, rid, tag, w) in enumerate(dir): + for i, (name, mbid, mw, mdir, rid, tag, w) in enumerate(dir): # some special situations worth reporting notes = [] - grmed = (max(mid, 0), rid) in gstate.grm + grmed = (max(mbid-max(mw-1, 0), 0), rid) in gstate.grm # grmed? if grmed: notes.append('grmed') @@ -1120,9 +1134,10 @@ def main(disk, mroots=None, *, '{%s}:' % ','.join('%04x' % block for block in it.chain([mdir.block], mdir.redund_blocks)) - if mid != pmid else '', - w_width, '%d.%d-%d' % (mid, rid-(w-1), rid) - if w > 1 else '%d.%d' % (mid, rid) + if mbid != pmbid else '', + w_width, '%d.%d-%d' % ( + mbid-max(mw-1, 0), rid-(w-1), rid) + if w > 1 else '%d.%d' % (mbid-max(mw-1, 0), rid) if w > 0 else '', f_width, '%s%s' % ( prefixes[0+(i==len(dir)-1)], @@ -1135,7 +1150,7 @@ def main(disk, mroots=None, *, if notes else '', '\x1b[m' if color and (grmed or tag == TAG_BOOKMARK) else '')) - pmid = mid + pmbid = mbid # print attrs associated with this file? if args.get('attrs'): diff --git a/scripts/dbgmtree.py b/scripts/dbgmtree.py index 58956918..9b3149c2 100755 --- a/scripts/dbgmtree.py +++ b/scripts/dbgmtree.py @@ -812,10 +812,10 @@ def main(disk, mroots=None, *, mweight = w # traverse entries - mid = -1 + mbid = -1 while True: - done, mid, w, rbyd, rid, tags, path = mtree.btree_lookup( - f, block_size, mid+1, + done, mbid, mw, rbyd, rid, tags, path = mtree.btree_lookup( + f, block_size, mbid+1, depth=args.get('depth', mdepth)-mdepth) if done: break @@ -962,10 +962,10 @@ def main(disk, mroots=None, *, # find the max depth of each mdir to nicely align trees mdepth_ = 0 - mid = -1 + mbid = -1 while True: - done, mid, w, rbyd, rid, tags, path = mtree.btree_lookup( - f, block_size, mid+1, + done, mbid, mw, rbyd, rid, tags, path = mtree.btree_lookup( + f, block_size, mbid+1, depth=args.get('depth', mdepth)-mdepth) if done: break @@ -992,10 +992,10 @@ def main(disk, mroots=None, *, mdepth_ = max(mdepth_, rdepth) # compute the rbyd-tree for each mdir - mid = -1 + mbid = -1 while True: - done, mid, w, rbyd, rid, tags, path = mtree.btree_lookup( - f, block_size, mid+1, + done, mbid, mw, rbyd, rid, tags, path = mtree.btree_lookup( + f, block_size, mbid+1, depth=args.get('depth', mdepth)-mdepth) if done: break @@ -1023,7 +1023,7 @@ def main(disk, mroots=None, *, # connect the root to the mtree branch = max( (branch for branch in tree - if branch.b[0] == mid-(w-1)), + if branch.b[0] == mbid-(mw-1)), key=lambda branch: branch.d, default=None) if branch: @@ -1037,7 +1037,7 @@ def main(disk, mroots=None, *, mdir_.lookup(-1, 0x1)) tree.add(TBranch( a=branch.b, - b=(mid-(w-1), len(path), 0, r_rid, r_tag), + b=(mbid-(mw-1), len(path), 0, r_rid, r_tag), d=d_ + tdepth, c='b', )) @@ -1047,8 +1047,8 @@ def main(disk, mroots=None, *, a_rid, a_tag = branch.a b_rid, b_tag = branch.b tree.add(TBranch( - a=(mid-(w-1), len(path), 0, a_rid, a_tag), - b=(mid-(w-1), len(path), 0, b_rid, b_tag), + a=(mbid-(mw-1), len(path), 0, a_rid, a_tag), + b=(mbid-(mw-1), len(path), 0, b_rid, b_tag), d=(d_ + tdepth + 1 + branch.d + mdepth_-rdepth), c=branch.c, @@ -1181,11 +1181,11 @@ def main(disk, mroots=None, *, # remap branches to leaves if we aren't showing inner branches if not args.get('inner'): - mid = -1 + mbid = -1 while True: - done, mid, w, rbyd, rid, tags, path = ( + done, mbid, mw, rbyd, rid, tags, path = ( mtree.btree_lookup( - f, block_size, mid+1, + f, block_size, mbid+1, depth=args.get('depth', mdepth)-mdepth)) if done: break @@ -1215,7 +1215,7 @@ def main(disk, mroots=None, *, tree_ = set() for branch in tree: - if branch.a[0] == mid-(w-1): + if branch.a[0] == mbid-(mw-1): a_bid, a_bd, _, _, _ = branch.a branch = TBranch( a=(a_bid, a_bd+1, 0, rid, tag), @@ -1223,7 +1223,7 @@ def main(disk, mroots=None, *, d=branch.d, c=branch.c, ) - if branch.b[0] == mid-(w-1): + if branch.b[0] == mbid-(mw-1): b_bid, b_bd, _, _, _ = branch.b branch = TBranch( a=branch.a, @@ -1241,7 +1241,7 @@ def main(disk, mroots=None, *, if t_depth > 0: t_width = 2*t_depth + 2 - def treerepr(mid, w, md, mrid, rid, tag): + def treerepr(mbid, mw, md, mrid, rid, tag): if t_depth == 0: return '' @@ -1276,7 +1276,7 @@ def main(disk, mroots=None, *, was = None for d in range(t_depth): t, c, was = branchrepr( - (mid-max(w-1, 0), md, mrid-max(w-1, 0), rid, tag), + (mbid-max(mw-1, 0), md, mrid-max(mw-1, 0), rid, tag), d, was) trunk.append('%s%s%s%s' % ( @@ -1291,7 +1291,7 @@ def main(disk, mroots=None, *, return '%s ' % ''.join(trunk) - def dbg_mdir(mdir, mid, md): + def dbg_mdir(mdir, mbid, mw, md): for i, (rid, tag, w, j, d, data) in enumerate(mdir): # show human-readable tag representation print('%12s %s%-57s' % ( @@ -1299,11 +1299,12 @@ def main(disk, mroots=None, *, for block in it.chain([mdir.block], mdir.redund_blocks)) if i == 0 else '', - treerepr(mid, 1, md, 0, rid, tag) + treerepr(mbid-max(mw-1, 0), 0, md, 0, rid, tag) if args.get('tree') or args.get('btree') else '', '%*s %-22s%s' % ( - w_width, '%d.%d-%d' % (mid, rid-(w-1), rid) - if w > 1 else '%d.%d' % (mid, rid) + w_width, '%d.%d-%d' % ( + mbid-max(mw-1, 0), rid-(w-1), rid) + if w > 1 else '%d.%d' % (mbid-max(mw-1, 0), rid) if w > 0 or i == 0 else '', tagrepr(tag, w, len(data), j), ' %s' % next(xxd(data, 8), '') @@ -1410,7 +1411,7 @@ def main(disk, mroots=None, *, print('%-11s %*s%-*s %-22s %s' % ( 'mdir', t_width, '', - w_width, 'ids', + w_width, 'mid', 'tag', 'data (truncated)' if not args.get('no_truncate') else '')) @@ -1435,7 +1436,7 @@ def main(disk, mroots=None, *, break else: # show the mdir - dbg_mdir(mroot, -1, d) + dbg_mdir(mroot, -1, 0, d) # stop here? if args.get('depth') and mdepth >= args.get('depth'): @@ -1469,7 +1470,7 @@ def main(disk, mroots=None, *, corrupted = True else: # show the mdir - dbg_mdir(mdir, 0, 0) + dbg_mdir(mdir, 0, 0, 0) # fetch the actual mtree, if there is one if not args.get('depth') or mdepth < args.get('depth'): @@ -1479,10 +1480,10 @@ def main(disk, mroots=None, *, mtree = Rbyd.fetch(f, block_size, block, trunk) # traverse entries - mid = -1 + mbid = -1 while True: - done, mid, w, rbyd, rid, tags, path = mtree.btree_lookup( - f, block_size, mid+1, + done, mbid, mw, rbyd, rid, tags, path = mtree.btree_lookup( + f, block_size, mbid+1, depth=args.get('depth', mdepth)-mdepth) if done: break @@ -1544,7 +1545,7 @@ def main(disk, mroots=None, *, # print btree entries in certain cases if args.get('inner') or not mdir__: - dbg_branch(mid, w, rbyd, rid, tags, len(path)-1) + dbg_branch(mbid, mw, rbyd, rid, tags, len(path)-1) if not mdir__: continue @@ -1567,7 +1568,7 @@ def main(disk, mroots=None, *, corrupted = True else: # show the mdir - dbg_mdir(mdir_, mid, len(path)) + dbg_mdir(mdir_, mbid, mw, len(path)) # force next btree entry to be shown prbyd = None diff --git a/scripts/dbgrbyd.py b/scripts/dbgrbyd.py index 6b6a2212..584b36d8 100755 --- a/scripts/dbgrbyd.py +++ b/scripts/dbgrbyd.py @@ -421,7 +421,7 @@ def dbg_log(data, block_size, rev, off, weight, *, print('%-8s %*s%-*s %-22s %s' % ( 'off', lifetime_width, '', - w_width, 'ids', + w_width, 'rid', 'tag', 'data (truncated)' if not args.get('no_truncate') else '')) @@ -750,7 +750,7 @@ def dbg_tree(data, block_size, rev, trunk, weight, *, print('%-8s %*s%-*s %-22s %s' % ( 'off', t_width, '', - w_width, 'ids', + w_width, 'rid', 'tag', 'data (truncated)' if not args.get('no_truncate') else '')) diff --git a/tests/test_mtree.toml b/tests/test_mtree.toml index a771f0f2..53d581e6 100644 --- a/tests/test_mtree.toml +++ b/tests/test_mtree.toml @@ -3485,8 +3485,9 @@ code = ''' if (tag_ == LFSR_TAG_BTREE) { lfsr_rbyd_t *branch = (lfsr_rbyd_t *)data_.u.b.buffer; - printf("traversal: %d 0x%x btree 0x%x.%x\n", - mid_, + printf("traversal: %d.%d 0x%x btree 0x%x.%x\n", + mid_ & lfsr_mbidmask(&lfs), + mid_ & lfsr_mridmask(&lfs), tag_, branch->block, branch->trunk); @@ -3494,8 +3495,9 @@ code = ''' seen[branch->block / 8] |= 1 << (branch->block % 8); } else if (tag_ == LFSR_TAG_MDIR) { lfsr_mdir_t *mdir = (lfsr_mdir_t*)data_.u.b.buffer; - printf("traversal: %d 0x%x mdir 0x{%x,%x}\n", - mid_, + printf("traversal: %d.%d 0x%x mdir 0x{%x,%x}\n", + mid_ & lfsr_mbidmask(&lfs), + mid_ & lfsr_mridmask(&lfs), tag_, mdir->u.m.blocks[0], mdir->u.m.blocks[1]); @@ -3504,8 +3506,9 @@ code = ''' seen[mdir->u.m.blocks[0] / 8] |= 1 << (mdir->u.m.blocks[0] % 8); } else { // this shouldn't happen - printf("traversal: %d 0x%x %d\n", - mid_, + printf("traversal: %d.%d 0x%x %d\n", + mid_ & lfsr_mbidmask(&lfs), + mid_ & lfsr_mridmask(&lfs), tag_, lfsr_data_size(&data_)); assert(false); @@ -3606,8 +3609,9 @@ code = ''' if (tag_ == LFSR_TAG_BTREE) { lfsr_rbyd_t *branch = (lfsr_rbyd_t *)data_.u.b.buffer; - printf("traversal: %d 0x%x btree 0x%x.%x\n", - mid_, + printf("traversal: %d.%d 0x%x btree 0x%x.%x\n", + mid_ & lfsr_mbidmask(&lfs), + mid_ & lfsr_mridmask(&lfs), tag_, branch->block, branch->trunk); @@ -3615,8 +3619,9 @@ code = ''' seen[branch->block / 8] |= 1 << (branch->block % 8); } else if (tag_ == LFSR_TAG_MDIR) { lfsr_mdir_t *mdir = (lfsr_mdir_t*)data_.u.b.buffer; - printf("traversal: %d 0x%x mdir 0x{%x,%x}\n", - mid_, + printf("traversal: %d.%d 0x%x mdir 0x{%x,%x}\n", + mid_ & lfsr_mbidmask(&lfs), + mid_ & lfsr_mridmask(&lfs), tag_, mdir->u.m.blocks[0], mdir->u.m.blocks[1]); @@ -3625,8 +3630,9 @@ code = ''' seen[mdir->u.m.blocks[0] / 8] |= 1 << (mdir->u.m.blocks[0] % 8); } else { // this shouldn't happen - printf("traversal: %d 0x%x %d\n", - mid_, + printf("traversal: %d.%d 0x%x %d\n", + mid_ & lfsr_mbidmask(&lfs), + mid_ & lfsr_mridmask(&lfs), tag_, lfsr_data_size(&data_)); assert(false); @@ -3738,8 +3744,9 @@ code = ''' if (tag_ == LFSR_TAG_BTREE) { lfsr_rbyd_t *branch = (lfsr_rbyd_t *)data_.u.b.buffer; - printf("traversal: %d 0x%x btree 0x%x.%x\n", - mid_, + printf("traversal: %d.%d 0x%x btree 0x%x.%x\n", + mid_ & lfsr_mbidmask(&lfs), + mid_ & lfsr_mridmask(&lfs), tag_, branch->block, branch->trunk); @@ -3747,8 +3754,9 @@ code = ''' seen[branch->block / 8] |= 1 << (branch->block % 8); } else if (tag_ == LFSR_TAG_MDIR) { lfsr_mdir_t *mdir = (lfsr_mdir_t*)data_.u.b.buffer; - printf("traversal: %d 0x%x mdir 0x{%x,%x}\n", - mid_, + printf("traversal: %d.%d 0x%x mdir 0x{%x,%x}\n", + mid_ & lfsr_mbidmask(&lfs), + mid_ & lfsr_mridmask(&lfs), tag_, mdir->u.m.blocks[0], mdir->u.m.blocks[1]); @@ -3757,8 +3765,9 @@ code = ''' seen[mdir->u.m.blocks[0] / 8] |= 1 << (mdir->u.m.blocks[0] % 8); } else { // this shouldn't happen - printf("traversal: %d 0x%x %d\n", - mid_, + printf("traversal: %d.%d 0x%x %d\n", + mid_ & lfsr_mbidmask(&lfs), + mid_ & lfsr_mridmask(&lfs), tag_, lfsr_data_size(&data_)); assert(false); @@ -3862,8 +3871,9 @@ code = ''' if (tag_ == LFSR_TAG_BTREE) { lfsr_rbyd_t *branch = (lfsr_rbyd_t *)data_.u.b.buffer; - printf("traversal: %d 0x%x btree 0x%x.%x\n", - mid_, + printf("traversal: %d.%d 0x%x btree 0x%x.%x\n", + mid_ & lfsr_mbidmask(&lfs), + mid_ & lfsr_mridmask(&lfs), tag_, branch->block, branch->trunk); @@ -3871,8 +3881,9 @@ code = ''' seen[branch->block / 8] |= 1 << (branch->block % 8); } else if (tag_ == LFSR_TAG_MDIR) { lfsr_mdir_t *mdir = (lfsr_mdir_t*)data_.u.b.buffer; - printf("traversal: %d 0x%x mdir 0x{%x,%x}\n", - mid_, + printf("traversal: %d.%d 0x%x mdir 0x{%x,%x}\n", + mid_ & lfsr_mbidmask(&lfs), + mid_ & lfsr_mridmask(&lfs), tag_, mdir->u.m.blocks[0], mdir->u.m.blocks[1]); @@ -3881,8 +3892,9 @@ code = ''' seen[mdir->u.m.blocks[0] / 8] |= 1 << (mdir->u.m.blocks[0] % 8); } else { // this shouldn't happen - printf("traversal: %d 0x%x %d\n", - mid_, + printf("traversal: %d.%d 0x%x %d\n", + mid_ & lfsr_mbidmask(&lfs), + mid_ & lfsr_mridmask(&lfs), tag_, lfsr_data_size(&data_)); assert(false); @@ -3997,8 +4009,9 @@ code = ''' if (tag_ == LFSR_TAG_BTREE) { lfsr_rbyd_t *branch = (lfsr_rbyd_t *)data_.u.b.buffer; - printf("traversal: %d 0x%x btree 0x%x.%x\n", - mid_, + printf("traversal: %d.%d 0x%x btree 0x%x.%x\n", + mid_ & lfsr_mbidmask(&lfs), + mid_ & lfsr_mridmask(&lfs), tag_, branch->block, branch->trunk); @@ -4006,8 +4019,9 @@ code = ''' seen[branch->block / 8] |= 1 << (branch->block % 8); } else if (tag_ == LFSR_TAG_MDIR) { lfsr_mdir_t *mdir = (lfsr_mdir_t*)data_.u.b.buffer; - printf("traversal: %d 0x%x mdir 0x{%x,%x}\n", - mid_, + printf("traversal: %d.%d 0x%x mdir 0x{%x,%x}\n", + mid_ & lfsr_mbidmask(&lfs), + mid_ & lfsr_mridmask(&lfs), tag_, mdir->u.m.blocks[0], mdir->u.m.blocks[1]); @@ -4016,8 +4030,9 @@ code = ''' seen[mdir->u.m.blocks[0] / 8] |= 1 << (mdir->u.m.blocks[0] % 8); } else { // this shouldn't happen - printf("traversal: %d 0x%x %d\n", - mid_, + printf("traversal: %d.%d 0x%x %d\n", + mid_ & lfsr_mbidmask(&lfs), + mid_ & lfsr_mridmask(&lfs), tag_, lfsr_data_size(&data_)); assert(false); @@ -4164,8 +4179,9 @@ code = ''' if (tag_ == LFSR_TAG_BTREE) { lfsr_rbyd_t *branch = (lfsr_rbyd_t *)data_.u.b.buffer; - printf("traversal: %d 0x%x btree 0x%x.%x\n", - mid_, + printf("traversal: %d.%d 0x%x btree 0x%x.%x\n", + mid_ & lfsr_mbidmask(&lfs), + mid_ & lfsr_mridmask(&lfs), tag_, branch->block, branch->trunk); @@ -4173,8 +4189,9 @@ code = ''' seen[branch->block / 8] |= 1 << (branch->block % 8); } else if (tag_ == LFSR_TAG_MDIR) { lfsr_mdir_t *mdir = (lfsr_mdir_t*)data_.u.b.buffer; - printf("traversal: %d 0x%x mdir 0x{%x,%x}\n", - mid_, + printf("traversal: %d.%d 0x%x mdir 0x{%x,%x}\n", + mid_ & lfsr_mbidmask(&lfs), + mid_ & lfsr_mridmask(&lfs), tag_, mdir->u.m.blocks[0], mdir->u.m.blocks[1]); @@ -4183,8 +4200,9 @@ code = ''' seen[mdir->u.m.blocks[0] / 8] |= 1 << (mdir->u.m.blocks[0] % 8); } else { // this shouldn't happen - printf("traversal: %d 0x%x %d\n", - mid_, + printf("traversal: %d.%d 0x%x %d\n", + mid_ & lfsr_mbidmask(&lfs), + mid_ & lfsr_mridmask(&lfs), tag_, lfsr_data_size(&data_)); assert(false); @@ -4270,20 +4288,23 @@ code = ''' if (tag_ == LFSR_TAG_BTREE) { lfsr_rbyd_t *branch = (lfsr_rbyd_t *)data_.u.b.buffer; - printf("traversal: %d 0x%x btree 0x%x.%x\n", - mid_, + printf("traversal: %d.%d 0x%x btree 0x%x.%x\n", + mid_ & lfsr_mbidmask(&lfs), + mid_ & lfsr_mridmask(&lfs), tag_, branch->block, branch->trunk); } else if (tag_ == LFSR_TAG_MDIR) { lfsr_mdir_t *mdir = (lfsr_mdir_t*)data_.u.b.buffer; - printf("traversal: %d 0x%x mdir 0x{%x,%x}\n", - mid_, + printf("traversal: %d.%d 0x%x mdir 0x{%x,%x}\n", + mid_ & lfsr_mbidmask(&lfs), + mid_ & lfsr_mridmask(&lfs), tag_, mdir->u.m.blocks[0], mdir->u.m.blocks[1]); } else { // this shouldn't happen - printf("traversal: %d 0x%x %d\n", - mid_, + printf("traversal: %d.%d 0x%x %d\n", + mid_ & lfsr_mbidmask(&lfs), + mid_ & lfsr_mridmask(&lfs), tag_, lfsr_data_size(&data_)); assert(false);