summaryrefslogtreecommitdiff
path: root/cmd
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@lukeshu.com>2022-06-06 22:38:48 -0600
committerLuke Shumaker <lukeshu@lukeshu.com>2022-06-06 22:38:48 -0600
commit5b6e8468680c2fc255b7f48ff6b72a6148534d9f (patch)
treee5072568d4c0643a52c5cbc26375df55375395ef /cmd
parent27cbe48c9ea535d12670d307a8dbbd5427a0ce1c (diff)
more
Diffstat (limited to 'cmd')
-rw-r--r--cmd/btrfs-fsck/main.go62
-rw-r--r--cmd/btrfs-fsck/pass2.go74
2 files changed, 77 insertions, 59 deletions
diff --git a/cmd/btrfs-fsck/main.go b/cmd/btrfs-fsck/main.go
index 2c52627..7ab5a44 100644
--- a/cmd/btrfs-fsck/main.go
+++ b/cmd/btrfs-fsck/main.go
@@ -5,7 +5,6 @@ import (
"os"
"lukeshu.com/btrfs-tools/pkg/btrfs"
- "lukeshu.com/btrfs-tools/pkg/btrfs/btrfsitem"
)
func main() {
@@ -22,7 +21,7 @@ func Main(imgfilename string) (err error) {
}
}
- fh, err := os.Open(imgfilename)
+ fh, err := os.OpenFile(imgfilename, os.O_RDWR, 0)
if err != nil {
return err
}
@@ -42,67 +41,12 @@ func Main(imgfilename string) (err error) {
return err
}
- _ /*allNodes*/, err = pass1(fs, superblock)
+ foundNodes, err := pass1(fs, superblock)
if err != nil {
return err
}
- fmt.Printf("\nPass 2: orphaned nodes\n") ///////////////////////////////////////////////////
- /*
+ pass2(fs, foundNodes)
- fmt.Printf("node@%d: physical_addr=0x%0X logical_addr=0x%0X generation=%d owner=%v level=%d\n",
- nodeRef.Addr,
- nodeRef.Addr, nodeRef.Data.Head.Addr,
- nodeRef.Data.Head.Generation, nodeRef.Data.Head.Owner, nodeRef.Data.Head.Level)
- srcPaddr := btrfs.QualifiedPhysicalAddr{
- Dev: superblock.Data.DevItem.DevUUID,
- Addr: nodeRef.Addr,
- }
- resPaddrs, _ := fs.Resolve(nodeRef.Data.Head.Addr)
- if len(resPaddrs) == 0 {
- fmt.Printf("node@%d: logical_addr=0x%0X is not mapped\n",
- nodeRef.Addr, nodeRef.Data.Head.Addr)
- } else if _, ok := resPaddrs[srcPaddr]; !ok {
- fmt.Printf("node@%d: logical_addr=0x%0X maps to %v, not %v\n",
- nodeRef.Addr, nodeRef.Data.Head.Addr, resPaddrs, srcPaddr)
- }
- */
return nil
}
-
-func walkFS(fs *btrfs.FS, cbs btrfs.WalkTreeHandler, errCb func(error)) {
- origItem := cbs.Item
- cbs.Item = func(key btrfs.Key, body btrfsitem.Item) error {
- if key.ItemType == btrfsitem.ROOT_ITEM_KEY {
- root, ok := body.(btrfsitem.Root)
- if !ok {
- errCb(fmt.Errorf("ROOT_ITEM_KEY is a %T, not a btrfsitem.Root", body))
- } else if err := fs.WalkTree(root.ByteNr, cbs); err != nil {
- errCb(err)
- }
- }
- if origItem != nil {
- return origItem(key, body)
- }
- return nil
- }
-
- superblock, err := fs.Superblock()
- if err != nil {
- errCb(err)
- return
- }
-
- if err := fs.WalkTree(superblock.Data.RootTree, cbs); err != nil {
- errCb(err)
- }
- if err := fs.WalkTree(superblock.Data.ChunkTree, cbs); err != nil {
- errCb(err)
- }
- if err := fs.WalkTree(superblock.Data.LogTree, cbs); err != nil {
- errCb(err)
- }
- if err := fs.WalkTree(superblock.Data.BlockGroupRoot, cbs); err != nil {
- errCb(err)
- }
-}
diff --git a/cmd/btrfs-fsck/pass2.go b/cmd/btrfs-fsck/pass2.go
new file mode 100644
index 0000000..3295b5d
--- /dev/null
+++ b/cmd/btrfs-fsck/pass2.go
@@ -0,0 +1,74 @@
+package main
+
+import (
+ "fmt"
+
+ "lukeshu.com/btrfs-tools/pkg/btrfs"
+ "lukeshu.com/btrfs-tools/pkg/btrfs/btrfsitem"
+ "lukeshu.com/btrfs-tools/pkg/util"
+)
+
+func walkFS(fs *btrfs.FS, cbs btrfs.WalkTreeHandler, errCb func(error)) {
+ origItem := cbs.Item
+ cbs.Item = func(key btrfs.Key, body btrfsitem.Item) error {
+ if key.ItemType == btrfsitem.ROOT_ITEM_KEY {
+ root, ok := body.(btrfsitem.Root)
+ if !ok {
+ errCb(fmt.Errorf("ROOT_ITEM_KEY is a %T, not a btrfsitem.Root", body))
+ } else if err := fs.WalkTree(root.ByteNr, cbs); err != nil {
+ errCb(err)
+ }
+ }
+ if origItem != nil {
+ return origItem(key, body)
+ }
+ return nil
+ }
+
+ superblock, err := fs.Superblock()
+ if err != nil {
+ errCb(err)
+ return
+ }
+
+ if err := fs.WalkTree(superblock.Data.RootTree, cbs); err != nil {
+ errCb(err)
+ }
+ if err := fs.WalkTree(superblock.Data.ChunkTree, cbs); err != nil {
+ errCb(err)
+ }
+ if err := fs.WalkTree(superblock.Data.LogTree, cbs); err != nil {
+ errCb(err)
+ }
+ if err := fs.WalkTree(superblock.Data.BlockGroupRoot, cbs); err != nil {
+ errCb(err)
+ }
+}
+
+func pass2(fs *btrfs.FS, foundNodes map[btrfs.LogicalAddr]struct{}) {
+ fmt.Printf("\nPass 2: orphaned nodes\n")
+
+ visitedNodes := make(map[btrfs.LogicalAddr]struct{})
+ walkFS(fs, btrfs.WalkTreeHandler{
+ Node: func(node *util.Ref[btrfs.LogicalAddr, btrfs.Node], err error) error {
+ if err != nil {
+ fmt.Printf("Pass 2: error: %v\n", err)
+ }
+ if node != nil {
+ visitedNodes[node.Addr] = struct{}{}
+ }
+ return nil
+ },
+ }, func(err error) {
+ fmt.Printf("Pass 2: error: %v\n", err)
+ })
+
+ orphanedNodes := make(map[btrfs.LogicalAddr]struct{})
+ for foundNode := range foundNodes {
+ if _, visited := visitedNodes[foundNode]; !visited {
+ orphanedNodes[foundNode] = struct{}{}
+ }
+ }
+
+ fmt.Printf("Pass 2: orphanedNodes=%#v\n", orphanedNodes)
+}