diff options
author | Luke Shumaker <lukeshu@lukeshu.com> | 2022-06-06 22:38:48 -0600 |
---|---|---|
committer | Luke Shumaker <lukeshu@lukeshu.com> | 2022-06-06 22:38:48 -0600 |
commit | 5b6e8468680c2fc255b7f48ff6b72a6148534d9f (patch) | |
tree | e5072568d4c0643a52c5cbc26375df55375395ef | |
parent | 27cbe48c9ea535d12670d307a8dbbd5427a0ce1c (diff) |
more
-rw-r--r-- | cmd/btrfs-fsck/main.go | 62 | ||||
-rw-r--r-- | cmd/btrfs-fsck/pass2.go | 74 |
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) +} |