From ff1cf2e06a30a096c5b7f9b0643a329250689bd1 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Wed, 13 Jul 2022 00:58:35 -0600 Subject: Add a TreePath.Node(x) method to help clean up the code --- lib/btrfs/io3_btree.go | 84 +++++++++++++++++-------------- lib/btrfsprogs/btrfsinspect/print_tree.go | 2 +- lib/btrfsprogs/btrfsrepair/clearnodes.go | 2 +- 3 files changed, 49 insertions(+), 39 deletions(-) diff --git a/lib/btrfs/io3_btree.go b/lib/btrfs/io3_btree.go index 5bbb8d1..6665d09 100644 --- a/lib/btrfs/io3_btree.go +++ b/lib/btrfs/io3_btree.go @@ -157,6 +157,16 @@ func (path TreePath) Append(elem TreePathElem) TreePath { return path } +// path.Node(x) is like path.Nodes[x], but negative values of x move +// down from the end of path.Nodes (similar to how lists work in many +// other languages, such as Python). +func (path TreePath) Node(x int) *TreePathElem { + if x < 0 { + x += len(path.Nodes) + } + return &path.Nodes[x] +} + type TreeError struct { Path TreePath Err error @@ -272,7 +282,7 @@ func (fs *FS) treeWalk(ctx context.Context, path TreePath, errHandle func(*TreeE if ctx.Err() != nil { return } - if path.Nodes[len(path.Nodes)-1].NodeAddr == 0 { + if path.Node(-1).NodeAddr == 0 { return } @@ -284,7 +294,7 @@ func (fs *FS) treeWalk(ctx context.Context, path TreePath, errHandle func(*TreeE return } } - node, err := fs.readNodeAtLevel(path.Nodes[len(path.Nodes)-1].NodeAddr, path.Nodes[len(path.Nodes)-1].NodeLevel) + node, err := fs.readNodeAtLevel(path.Node(-1).NodeAddr, path.Node(-1).NodeLevel) if ctx.Err() != nil { return } @@ -378,10 +388,10 @@ func (fs *FS) treeSearch(treeRoot treeRoot, fn func(Key) int) (TreePath, *util.R }, } for { - if path.Nodes[len(path.Nodes)-1].NodeAddr == 0 { + if path.Node(-1).NodeAddr == 0 { return TreePath{}, nil, iofs.ErrNotExist } - node, err := fs.readNodeAtLevel(path.Nodes[len(path.Nodes)-1].NodeAddr, path.Nodes[len(path.Nodes)-1].NodeLevel) + node, err := fs.readNodeAtLevel(path.Node(-1).NodeAddr, path.Node(-1).NodeLevel) if err != nil { return TreePath{}, nil, err } @@ -456,27 +466,27 @@ func (fs *FS) prev(path TreePath, node *util.Ref[btrfsvol.LogicalAddr, Node]) (T path = path.DeepCopy() // go up - for path.Nodes[len(path.Nodes)-1].ItemIdx < 1 { + for path.Node(-1).ItemIdx < 1 { path.Nodes = path.Nodes[:len(path.Nodes)-1] if len(path.Nodes) == 0 { return TreePath{}, nil, nil } } // go left - path.Nodes[len(path.Nodes)-1].ItemIdx-- - if path.Nodes[len(path.Nodes)-1].NodeAddr != 0 { - if node.Addr != path.Nodes[len(path.Nodes)-2].NodeAddr { - node, err = fs.readNodeAtLevel(path.Nodes[len(path.Nodes)-2].NodeAddr, path.Nodes[len(path.Nodes)-2].NodeLevel) + path.Node(-1).ItemIdx-- + if path.Node(-1).NodeAddr != 0 { + if node.Addr != path.Node(-2).NodeAddr { + node, err = fs.readNodeAtLevel(path.Node(-2).NodeAddr, path.Node(-2).NodeLevel) if err != nil { return TreePath{}, nil, err } - path.Nodes[len(path.Nodes)-1].NodeAddr = node.Data.BodyInternal[path.Nodes[len(path.Nodes)-1].ItemIdx].BlockPtr + path.Node(-1).NodeAddr = node.Data.BodyInternal[path.Node(-1).ItemIdx].BlockPtr } } // go down - for path.Nodes[len(path.Nodes)-1].NodeAddr != 0 { - if node.Addr != path.Nodes[len(path.Nodes)-1].NodeAddr { - node, err = fs.readNodeAtLevel(path.Nodes[len(path.Nodes)-1].NodeAddr, path.Nodes[len(path.Nodes)-1].NodeLevel) + for path.Node(-1).NodeAddr != 0 { + if node.Addr != path.Node(-1).NodeAddr { + node, err = fs.readNodeAtLevel(path.Node(-1).NodeAddr, path.Node(-1).NodeLevel) if err != nil { return TreePath{}, nil, err } @@ -494,8 +504,8 @@ func (fs *FS) prev(path TreePath, node *util.Ref[btrfsvol.LogicalAddr, Node]) (T } } // return - if node.Addr != path.Nodes[len(path.Nodes)-2].NodeAddr { - node, err = fs.readNodeAtLevel(path.Nodes[len(path.Nodes)-2].NodeAddr, path.Nodes[len(path.Nodes)-2].NodeLevel) + if node.Addr != path.Node(-2).NodeAddr { + node, err = fs.readNodeAtLevel(path.Node(-2).NodeAddr, path.Node(-2).NodeLevel) if err != nil { return TreePath{}, nil, err } @@ -508,45 +518,45 @@ func (fs *FS) next(path TreePath, node *util.Ref[btrfsvol.LogicalAddr, Node]) (T path = path.DeepCopy() // go up - if node.Addr != path.Nodes[len(path.Nodes)-2].NodeAddr { - node, err = fs.readNodeAtLevel(path.Nodes[len(path.Nodes)-2].NodeAddr, path.Nodes[len(path.Nodes)-2].NodeLevel) + if node.Addr != path.Node(-2).NodeAddr { + node, err = fs.readNodeAtLevel(path.Node(-2).NodeAddr, path.Node(-2).NodeLevel) if err != nil { return TreePath{}, nil, err } - path.Nodes[len(path.Nodes)-2].NodeLevel = node.Data.Head.Level + path.Node(-2).NodeLevel = node.Data.Head.Level } - for path.Nodes[len(path.Nodes)-1].ItemIdx+1 >= int(node.Data.Head.NumItems) { + for path.Node(-1).ItemIdx+1 >= int(node.Data.Head.NumItems) { path.Nodes = path.Nodes[:len(path.Nodes)-1] if len(path.Nodes) == 1 { return TreePath{}, nil, nil } - if node.Addr != path.Nodes[len(path.Nodes)-2].NodeAddr { - node, err = fs.readNodeAtLevel(path.Nodes[len(path.Nodes)-2].NodeAddr, path.Nodes[len(path.Nodes)-2].NodeLevel) + if node.Addr != path.Node(-2).NodeAddr { + node, err = fs.readNodeAtLevel(path.Node(-2).NodeAddr, path.Node(-2).NodeLevel) if err != nil { return TreePath{}, nil, err } - path.Nodes[len(path.Nodes)-2].NodeLevel = node.Data.Head.Level + path.Node(-2).NodeLevel = node.Data.Head.Level } } // go left - path.Nodes[len(path.Nodes)-1].ItemIdx++ - if path.Nodes[len(path.Nodes)-1].NodeAddr != 0 { - if node.Addr != path.Nodes[len(path.Nodes)-2].NodeAddr { - node, err = fs.readNodeAtLevel(path.Nodes[len(path.Nodes)-2].NodeAddr, path.Nodes[len(path.Nodes)-2].NodeLevel) + path.Node(-1).ItemIdx++ + if path.Node(-1).NodeAddr != 0 { + if node.Addr != path.Node(-2).NodeAddr { + node, err = fs.readNodeAtLevel(path.Node(-2).NodeAddr, path.Node(-2).NodeLevel) if err != nil { return TreePath{}, nil, err } - path.Nodes[len(path.Nodes)-1].NodeAddr = node.Data.BodyInternal[path.Nodes[len(path.Nodes)-1].ItemIdx].BlockPtr + path.Node(-1).NodeAddr = node.Data.BodyInternal[path.Node(-1).ItemIdx].BlockPtr } } // go down - for path.Nodes[len(path.Nodes)-1].NodeAddr != 0 { - if node.Addr != path.Nodes[len(path.Nodes)-1].NodeAddr { - node, err = fs.readNodeAtLevel(path.Nodes[len(path.Nodes)-1].NodeAddr, path.Nodes[len(path.Nodes)-1].NodeLevel) + for path.Node(-1).NodeAddr != 0 { + if node.Addr != path.Node(-1).NodeAddr { + node, err = fs.readNodeAtLevel(path.Node(-1).NodeAddr, path.Node(-1).NodeLevel) if err != nil { return TreePath{}, nil, err } - path.Nodes[len(path.Nodes)-1].NodeLevel = node.Data.Head.Level + path.Node(-1).NodeLevel = node.Data.Head.Level } if node.Data.Head.Level > 0 { path = path.Append(TreePathElem{ @@ -561,8 +571,8 @@ func (fs *FS) next(path TreePath, node *util.Ref[btrfsvol.LogicalAddr, Node]) (T } } // return - if node.Addr != path.Nodes[len(path.Nodes)-2].NodeAddr { - node, err = fs.readNodeAtLevel(path.Nodes[len(path.Nodes)-2].NodeAddr, path.Nodes[len(path.Nodes)-2].NodeLevel) + if node.Addr != path.Node(-2).NodeAddr { + node, err = fs.readNodeAtLevel(path.Node(-2).NodeAddr, path.Node(-2).NodeLevel) if err != nil { return TreePath{}, nil, err } @@ -579,7 +589,7 @@ func (fs *FS) TreeSearch(treeID ObjID, fn func(Key) int) (Item, error) { if err != nil { return Item{}, err } - return node.Data.BodyLeaf[path.Nodes[len(path.Nodes)-1].ItemIdx], nil + return node.Data.BodyLeaf[path.Node(-1).ItemIdx], nil } func (fs *FS) TreeLookup(treeID ObjID, key Key) (Item, error) { @@ -599,7 +609,7 @@ func (fs *FS) TreeSearchAll(treeID ObjID, fn func(Key) int) ([]Item, error) { if err != nil { return nil, err } - middleItem := middleNode.Data.BodyLeaf[middlePath.Nodes[len(middlePath.Nodes)-1].ItemIdx] + middleItem := middleNode.Data.BodyLeaf[middlePath.Node(-1).ItemIdx] var ret = []Item{middleItem} var errs derror.MultiError @@ -612,7 +622,7 @@ func (fs *FS) TreeSearchAll(treeID ObjID, fn func(Key) int) ([]Item, error) { if len(prevPath.Nodes) == 0 { break } - prevItem := prevNode.Data.BodyLeaf[prevPath.Nodes[len(prevPath.Nodes)-1].ItemIdx] + prevItem := prevNode.Data.BodyLeaf[prevPath.Node(-1).ItemIdx] if fn(prevItem.Key) != 0 { break } @@ -628,7 +638,7 @@ func (fs *FS) TreeSearchAll(treeID ObjID, fn func(Key) int) ([]Item, error) { if len(nextPath.Nodes) == 0 { break } - nextItem := nextNode.Data.BodyLeaf[nextPath.Nodes[len(nextPath.Nodes)-1].ItemIdx] + nextItem := nextNode.Data.BodyLeaf[nextPath.Node(-1).ItemIdx] if fn(nextItem.Key) != 0 { break } diff --git a/lib/btrfsprogs/btrfsinspect/print_tree.go b/lib/btrfsprogs/btrfsinspect/print_tree.go index 142f5e5..5d3b4ef 100644 --- a/lib/btrfsprogs/btrfsinspect/print_tree.go +++ b/lib/btrfsprogs/btrfsinspect/print_tree.go @@ -107,7 +107,7 @@ func printTree(ctx context.Context, out io.Writer, fs *btrfs.FS, treeID btrfs.Ob return nil }, Item: func(path btrfs.TreePath, item btrfs.Item) error { - i := path.Nodes[len(path.Nodes)-1].ItemIdx + i := path.Node(-1).ItemIdx bs, _ := binstruct.Marshal(item.Body) itemSize := uint32(len(bs)) itemOffset -= itemSize diff --git a/lib/btrfsprogs/btrfsrepair/clearnodes.go b/lib/btrfsprogs/btrfsrepair/clearnodes.go index b38a333..9fa5a6a 100644 --- a/lib/btrfsprogs/btrfsrepair/clearnodes.go +++ b/lib/btrfsprogs/btrfsrepair/clearnodes.go @@ -57,7 +57,7 @@ func ClearBadNodes(ctx context.Context, fs *btrfs.FS) error { Generation: 0, Owner: path.TreeID, NumItems: 0, - Level: path.Nodes[len(path.Nodes)-1].NodeLevel, + Level: path.Node(-1).NodeLevel, }, } node.Data.Head.Checksum, err = node.Data.CalculateChecksum() -- cgit v1.2.3-2-g168b