summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/btrfs/btrfstree/path.go51
-rw-r--r--lib/btrfs/btrfstree/readnode.go53
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
-}