diff options
-rw-r--r-- | lib/btrfs/btrfstree/path.go | 51 | ||||
-rw-r--r-- | lib/btrfs/btrfstree/readnode.go | 53 |
2 files changed, 51 insertions, 53 deletions
diff --git a/lib/btrfs/btrfstree/path.go b/lib/btrfs/btrfstree/path.go index c07d8a0..1335b76 100644 --- a/lib/btrfs/btrfstree/path.go +++ b/lib/btrfs/btrfstree/path.go @@ -11,6 +11,7 @@ import ( "git.lukeshu.com/btrfs-progs-ng/lib/btrfs/btrfsprim" "git.lukeshu.com/btrfs-progs-ng/lib/btrfs/btrfsvol" + "git.lukeshu.com/btrfs-progs-ng/lib/containers" ) // Path is a path from the superblock (i.e. the root of the btrfs @@ -123,6 +124,56 @@ func (path Path) DeepCopy() Path { return append(Path(nil), path...) } +// NodeExpectations returns the address to read and the expectations +// to have when reading the node pointed to by this Path. +// +// `ok` is false if the path is empty or if this Path points to an +// item rather than a node. +func (path Path) NodeExpectations(fs NodeFile) (_ btrfsvol.LogicalAddr, _ NodeExpectations, ok bool) { + if path.Node(-1).ToNodeAddr == 0 && path.Node(-1).ToNodeGeneration == 0 && path.Node(-1).ToNodeLevel == 0 { + return 0, NodeExpectations{}, false + } + + checkOwner := func(owner btrfsprim.ObjID, gen btrfsprim.Generation) error { + var treeParents []btrfsprim.ObjID + + tree := path.Node(-1).FromTree + for { + if owner == tree { + // OK! + return nil + } + + treeParents = append(treeParents, tree) + parent, parentGen, parentOK := fs.ParentTree(tree) + if !parentOK { + // Failed look up parent info; fail open. + return nil + } + + if parent == 0 { + // End of the line. + return fmt.Errorf("expected owner in %v but claims to have owner=%v", + treeParents, owner) + } + if gen > parentGen { + return fmt.Errorf("claimed owner=%v might be acceptable in this tree (if generation<=%v) but not with claimed generation=%v", + owner, parentGen, gen) + } + tree = parent + } + } + + return path.Node(-1).ToNodeAddr, NodeExpectations{ + LAddr: containers.OptionalValue(path.Node(-1).ToNodeAddr), + Level: containers.OptionalValue(path.Node(-1).ToNodeLevel), + Generation: containers.OptionalValue(path.Node(-1).ToNodeGeneration), + Owner: checkOwner, + MinItem: containers.OptionalValue(path.Node(-1).ToKey), + MaxItem: containers.OptionalValue(path.Node(-1).ToMaxKey), + }, true +} + func (path Path) Parent() Path { return path[:len(path)-1] } diff --git a/lib/btrfs/btrfstree/readnode.go b/lib/btrfs/btrfstree/readnode.go index a4ccf10..c9642da 100644 --- a/lib/btrfs/btrfstree/readnode.go +++ b/lib/btrfs/btrfstree/readnode.go @@ -5,11 +5,8 @@ package btrfstree import ( - "fmt" - "git.lukeshu.com/btrfs-progs-ng/lib/btrfs/btrfsprim" "git.lukeshu.com/btrfs-progs-ng/lib/btrfs/btrfsvol" - "git.lukeshu.com/btrfs-progs-ng/lib/containers" "git.lukeshu.com/btrfs-progs-ng/lib/diskio" ) @@ -27,53 +24,3 @@ type NodeFile interface { // looked up ParentTree(btrfsprim.ObjID) (btrfsprim.ObjID, btrfsprim.Generation, bool) } - -// NodeExpectations returns the address to read and the expectations -// to have when reading the node pointed to by this Path. -// -// `ok` is false if the path is empty or if this Path points to an -// item rather than a node. -func (path Path) NodeExpectations(fs NodeFile) (_ btrfsvol.LogicalAddr, _ NodeExpectations, ok bool) { - if path.Node(-1).ToNodeAddr == 0 && path.Node(-1).ToNodeGeneration == 0 && path.Node(-1).ToNodeLevel == 0 { - return 0, NodeExpectations{}, false - } - - checkOwner := func(owner btrfsprim.ObjID, gen btrfsprim.Generation) error { - var treeParents []btrfsprim.ObjID - - tree := path.Node(-1).FromTree - for { - if owner == tree { - // OK! - return nil - } - - treeParents = append(treeParents, tree) - parent, parentGen, parentOK := fs.ParentTree(tree) - if !parentOK { - // Failed look up parent info; fail open. - return nil - } - - if parent == 0 { - // End of the line. - return fmt.Errorf("expected owner in %v but claims to have owner=%v", - treeParents, owner) - } - if gen > parentGen { - return fmt.Errorf("claimed owner=%v might be acceptable in this tree (if generation<=%v) but not with claimed generation=%v", - owner, parentGen, gen) - } - tree = parent - } - } - - return path.Node(-1).ToNodeAddr, NodeExpectations{ - LAddr: containers.OptionalValue(path.Node(-1).ToNodeAddr), - Level: containers.OptionalValue(path.Node(-1).ToNodeLevel), - Generation: containers.OptionalValue(path.Node(-1).ToNodeGeneration), - Owner: checkOwner, - MinItem: containers.OptionalValue(path.Node(-1).ToKey), - MaxItem: containers.OptionalValue(path.Node(-1).ToMaxKey), - }, true -} |