diff options
author | Luke Shumaker <lukeshu@lukeshu.com> | 2022-07-10 17:24:51 -0600 |
---|---|---|
committer | Luke Shumaker <lukeshu@lukeshu.com> | 2022-07-11 00:44:30 -0600 |
commit | bde202f286461ab575dc7e3d83f996d9a5f4a6ec (patch) | |
tree | 64782c354c15f64a164996125a06c1bca30c9aa7 /lib/btrfsprogs/btrfsrepair | |
parent | d2da99882ea49cc67780c0255bf624698898e7fe (diff) |
Have a go at rearranging things in to a lib/btrfsprogs
Diffstat (limited to 'lib/btrfsprogs/btrfsrepair')
-rw-r--r-- | lib/btrfsprogs/btrfsrepair/clearnodes.go | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/lib/btrfsprogs/btrfsrepair/clearnodes.go b/lib/btrfsprogs/btrfsrepair/clearnodes.go new file mode 100644 index 0000000..595fef0 --- /dev/null +++ b/lib/btrfsprogs/btrfsrepair/clearnodes.go @@ -0,0 +1,91 @@ +// Copyright (C) 2022 Luke Shumaker <lukeshu@lukeshu.com> +// +// SPDX-License-Identifier: GPL-2.0-or-later + +package btrfsrepair + +import ( + "errors" + "fmt" + + "git.lukeshu.com/btrfs-progs-ng/lib/btrfs" + "git.lukeshu.com/btrfs-progs-ng/lib/btrfs/btrfsvol" + "git.lukeshu.com/btrfs-progs-ng/lib/btrfsprogs/btrfsutil" + "git.lukeshu.com/btrfs-progs-ng/lib/util" +) + +func ClearBadNodes(fs *btrfs.FS) error { + var uuidsInited bool + var metadataUUID, chunkTreeUUID btrfs.UUID + + var treeName string + var treeID btrfs.ObjID + btrfsutil.WalkAllTrees(fs, btrfsutil.WalkAllTreesHandler{ + PreTree: func(name string, id btrfs.ObjID) { + treeName = name + treeID = id + }, + Err: func(err error) { + fmt.Printf("error: %v\n", err) + }, + UnsafeNodes: true, + TreeWalkHandler: btrfs.TreeWalkHandler{ + Node: func(path btrfs.TreePath, node *util.Ref[btrfsvol.LogicalAddr, btrfs.Node], err error) error { + if err == nil { + if !uuidsInited { + metadataUUID = node.Data.Head.MetadataUUID + chunkTreeUUID = node.Data.Head.ChunkTreeUUID + uuidsInited = true + } + return nil + } + if !errors.Is(err, btrfs.ErrNotANode) { + err = btrfsutil.WalkErr{ + TreeName: treeName, + Path: path, + Err: err, + } + fmt.Printf("error: %v\n", err) + return nil + } + origErr := err + if !uuidsInited { + // TODO(lukeshu): Is there a better way to get the chunk + // tree UUID? + return fmt.Errorf("cannot repair node@%v: not (yet?) sure what the chunk tree UUID is", node.Addr) + } + node.Data = btrfs.Node{ + Size: node.Data.Size, + ChecksumType: node.Data.ChecksumType, + Head: btrfs.NodeHeader{ + //Checksum: filled below, + MetadataUUID: metadataUUID, + Addr: node.Addr, + Flags: btrfs.NodeWritten, + BackrefRev: btrfs.MixedBackrefRev, + ChunkTreeUUID: chunkTreeUUID, + Generation: 0, + Owner: treeID, + NumItems: 0, + Level: path[len(path)-1].NodeLevel, + }, + } + node.Data.Head.Checksum, err = node.Data.CalculateChecksum() + if err != nil { + return btrfsutil.WalkErr{ + TreeName: treeName, + Path: path, + Err: err, + } + } + if err := node.Write(); err != nil { + return err + } + + fmt.Printf("fixed node@%v (err was %v)\n", node.Addr, origErr) + return nil + }, + }, + }) + return nil +} |