Added bshrub support to dbgbmap.py

Forgot about this script.
This commit is contained in:
Christopher Haster
2024-01-21 20:06:22 -06:00
parent 991f04a4fb
commit e8b1be17fe
+93 -59
View File
@@ -163,6 +163,12 @@ def frommdir(data):
d += d_ d += d_
return blocks return blocks
def fromshrub(data):
d = 0
weight, d_ = fromleb128(data[d:]); d += d_
trunk, d_ = fromleb128(data[d:]); d += d_
return weight, trunk
def frombranch(data): def frombranch(data):
d = 0 d = 0
block, d_ = fromleb128(data[d:]); d += d_ block, d_ = fromleb128(data[d:]); d += d_
@@ -1214,7 +1220,7 @@ class Rbyd:
done, rid_, tag_, w_, j, d, data, _ = rbyd.lookup(rid, TAG_STRUCT) done, rid_, tag_, w_, j, d, data, _ = rbyd.lookup(rid, TAG_STRUCT)
# found another branch # found another branch
if tag_ == TAG_BRANCH: if tag_ & 0xfff == TAG_BRANCH:
# update our bid # update our bid
bid += rid - (w-1) bid += rid - (w-1)
@@ -1489,8 +1495,11 @@ def main(disk, mroots=None, *,
# find any file btrees in our mroot # find any file btrees in our mroot
for rid, tag, w, j, d, data in mroot: for rid, tag, w, j, d, data in mroot:
if tag == TAG_BLOCK or tag == TAG_BTREE: if (tag == TAG_DATA
btrees__.append((tag, data)) or tag == TAG_BLOCK
or tag == TAG_BSHRUB
or tag == TAG_BTREE):
btrees__.append((mroot, tag, data))
# stop here? # stop here?
if args.get('depth') and mdepth >= args.get('depth'): if args.get('depth') and mdepth >= args.get('depth'):
@@ -1525,8 +1534,11 @@ def main(disk, mroots=None, *,
# find any file btrees in our mdir # find any file btrees in our mdir
for rid, tag, w, j, d, data in mdir: for rid, tag, w, j, d, data in mdir:
if tag == TAG_BLOCK or tag == TAG_BTREE: if (tag == TAG_DATA
btrees__.append((tag, data)) or tag == TAG_BLOCK
or tag == TAG_BSHRUB
or tag == TAG_BTREE):
btrees__.append((mdir, tag, data))
# fetch the actual mtree, if there is one # fetch the actual mtree, if there is one
mtree = None mtree = None
@@ -1599,81 +1611,103 @@ def main(disk, mroots=None, *,
# find any file btrees in our mdir # find any file btrees in our mdir
for rid, tag, w, j, d, data in mdir_: for rid, tag, w, j, d, data in mdir_:
if tag == TAG_BLOCK or tag == TAG_BTREE: if (tag == TAG_DATA
btrees__.append((tag, data)) or tag == TAG_BLOCK
or tag == TAG_BSHRUB
or tag == TAG_BTREE):
btrees__.append((mdir_, tag, data))
# fetch any file btrees we found # fetch any file btrees we found
if not args.get('depth') or mdepth < args.get('depth'): if not args.get('depth') or mdepth < args.get('depth'):
for tag, data in btrees__: for mdir, tag, data in btrees__:
# inlined data?
if tag == TAG_DATA:
# ignore here
continue
# direct block? # direct block?
if tag == TAG_BLOCK: elif tag == TAG_BLOCK:
size, block, off = frombptr(data) size, block, off = frombptr(data)
# mark block in our bmap # mark block in our bmap
bmap.data(block, bmap.data(block,
off if args.get('in_use') else 0, off if args.get('in_use') else 0,
size if args.get('in_use') else block_size) size if args.get('in_use') else block_size)
datas_ += 1 datas_ += 1
continue
# inlined bshrub?
elif tag == TAG_BSHRUB:
weight, trunk = fromshrub(data)
btree = Rbyd.fetch(f, block_size, mdir.block, trunk)
shrub = True
# indirect btree? # indirect btree?
elif tag == TAG_BTREE: elif tag == TAG_BTREE:
w, block, trunk, cksum = frombtree(data) w, block, trunk, cksum = frombtree(data)
btree = Rbyd.fetch(f, block_size, block, trunk) btree = Rbyd.fetch(f, block_size, block, trunk)
shrub = False
# traverse entries else:
bid = -1 assert False
ppath = []
while True: # traverse entries
(done, bid, w, rbyd, rid, tags, path bid = -1
) = btree.btree_lookup( ppath = []
f, block_size, bid+1, while True:
depth=args.get('depth', mdepth)-mdepth) (done, bid, w, rbyd, rid, tags, path
if done: ) = btree.btree_lookup(
f, block_size, bid+1,
depth=args.get('depth', mdepth)-mdepth)
if done:
break
# traverse the inner btree nodes
changed = False
for (x, px) in it.zip_longest(
enumerate(path),
enumerate(ppath)):
if x is None:
break break
if not (changed or px is None or x[0] != px[0]):
# traverse the inner btree nodes
changed = False
for (x, px) in it.zip_longest(
enumerate(path),
enumerate(ppath)):
if x is None:
break
if not (changed or px is None or x[0] != px[0]):
continue
changed = True
# mark btree inner nodes in our bmap
d, (mid_, w_, rbyd_, rid_, tags_) = x
for block in rbyd_.blocks:
bmap.btree(block,
rbyd_.eoff if args.get('in_use')
else block_size)
btrees_ += 1
ppath = path
# corrupted?
if not rbyd:
corrupted = True
continue continue
changed = True
# found a block in the tags? # mark btree inner nodes in our bmap
bptr__ = None d, (mid_, w_, rbyd_, rid_, tags_) = x
if (not args.get('depth') # ignore bshrub roots
or mdepth+len(path) < args.get('depth')): if shrub and d == 0:
bptr__ = next(((tag, j, d, data) continue
for tag, j, d, data in tags for block in rbyd_.blocks:
if tag == TAG_BLOCK), bmap.btree(block,
None) rbyd_.eoff if args.get('in_use')
else block_size)
btrees_ += 1
ppath = path
if bptr__: # corrupted?
# fetch the block if not rbyd:
_, _, _, data = bptr__ corrupted = True
size, block, off = frombptr(data) continue
# mark blocks in our bmap # found a block in the tags?
bmap.data(block, bptr__ = None
off if args.get('in_use') else 0, if (not args.get('depth')
size if args.get('in_use') else block_size) or mdepth+len(path) < args.get('depth')):
datas_ += 1 bptr__ = next(((tag, j, d, data)
for tag, j, d, data in tags
if tag & 0xfff == TAG_BLOCK),
None)
if bptr__:
# fetch the block
_, _, _, data = bptr__
size, block, off = frombptr(data)
# mark blocks in our bmap
bmap.data(block,
off if args.get('in_use') else 0,
size if args.get('in_use') else block_size)
datas_ += 1
#### actual rendering begins here #### actual rendering begins here