diff options
author | Luke Shumaker <lukeshu@lukeshu.com> | 2023-03-22 17:25:54 -0400 |
---|---|---|
committer | Luke Shumaker <lukeshu@lukeshu.com> | 2023-03-23 18:36:55 -0600 |
commit | 418553acc64567ebc95122e28b07657526c92923 (patch) | |
tree | 9cb910940a1e16982f5c5012a4fbeb37ba172f82 /lib/btrfs/btrfstree/readnode.go | |
parent | d11a5357df7d155a7a3e92a67971d3d52ff6ad86 (diff) |
btrfs: Consider the generation when checking if a node owner is OK
Diffstat (limited to 'lib/btrfs/btrfstree/readnode.go')
-rw-r--r-- | lib/btrfs/btrfstree/readnode.go | 34 |
1 files changed, 21 insertions, 13 deletions
diff --git a/lib/btrfs/btrfstree/readnode.go b/lib/btrfs/btrfstree/readnode.go index 7cc42f5..ac82c62 100644 --- a/lib/btrfs/btrfstree/readnode.go +++ b/lib/btrfs/btrfstree/readnode.go @@ -20,13 +20,13 @@ type NodeFile interface { // ParentTree, given a tree ID, returns that tree's parent // tree, if it has one. // - // - non-zero, true : the parent tree ID + // - non-zero, ?, true : the parent tree ID // - // - 0, true : the tree does not have a parent + // - 0, 0, true : the tree does not have a parent // - // - any, false : the tree's parent information could not be + // - ?, ?, false : the tree's parent information could not be // looked up - ParentTree(btrfsprim.ObjID) (btrfsprim.ObjID, bool) + ParentTree(btrfsprim.ObjID) (btrfsprim.ObjID, btrfsprim.Generation, bool) } // FSReadNode is a utility function to help with implementing the @@ -40,25 +40,33 @@ func FSReadNode( return nil, fmt.Errorf("btrfs.FS.ReadNode: %w", err) } - var treeParents []btrfsprim.ObjID - checkOwner := func(owner btrfsprim.ObjID, _ btrfsprim.Generation) error { - exp := path.Node(-1).FromTree + checkOwner := func(owner btrfsprim.ObjID, gen btrfsprim.Generation) error { + var treeParents []btrfsprim.ObjID + + tree := path.Node(-1).FromTree for { - if owner == exp { + if owner == tree { + // OK! return nil } - treeParents = append(treeParents, exp) - var ok bool - exp, ok = fs.ParentTree(exp) - if !ok { + + treeParents = append(treeParents, tree) + parent, parentGen, parentOK := fs.ParentTree(tree) + if !parentOK { // Failed look up parent info; fail open. return nil } - if exp == 0 { + + 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 } } |