summaryrefslogtreecommitdiff
path: root/cmd
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@lukeshu.com>2022-06-05 22:45:47 -0600
committerLuke Shumaker <lukeshu@lukeshu.com>2022-06-05 22:45:47 -0600
commit5c02065e573ce42d9d83099b524566878ba61bdb (patch)
tree9f21c98fe2d7a44694252f6f2b3bc20a23911b93 /cmd
parent5626918663de1d3f606850e25a5b39f940ceb7a2 (diff)
proper multi-dev
Diffstat (limited to 'cmd')
-rw-r--r--cmd/btrfs-fsck/main.go142
1 files changed, 72 insertions, 70 deletions
diff --git a/cmd/btrfs-fsck/main.go b/cmd/btrfs-fsck/main.go
index 7823c8d..97b1571 100644
--- a/cmd/btrfs-fsck/main.go
+++ b/cmd/btrfs-fsck/main.go
@@ -70,86 +70,88 @@ func Main(imgfilename string) (err error) {
fmt.Printf("Pass 1: ... walk chunk tree: error: %v\n", err)
}
- fmt.Printf("Pass 1: ... scanning for nodes\n")
- foundNodes := make(map[btrfs.LogicalAddr][]btrfs.PhysicalAddr)
- var lostAndFoundChunks []btrfs.SysChunk
- if err := btrfsmisc.ScanForNodes(fs.Devices[0], superblock.Data, func(nodeRef *util.Ref[btrfs.PhysicalAddr, btrfs.Node], err error) {
- if err != nil {
- fmt.Println(err)
- return
- }
- foundNodes[nodeRef.Data.Head.Addr] = append(foundNodes[nodeRef.Data.Head.Addr], nodeRef.Addr)
- _, alreadyVisited := visitedChunkNodes[nodeRef.Data.Head.Addr]
- if nodeRef.Data.Head.Owner == btrfs.CHUNK_TREE_OBJECTID && !alreadyVisited {
- for i, item := range nodeRef.Data.BodyLeaf {
- if item.Head.Key.ItemType != btrfsitem.CHUNK_ITEM_KEY {
- continue
- }
- chunk, ok := item.Body.(btrfsitem.Chunk)
- if !ok {
- fmt.Printf("Pass 1: node@%d: item %d: error: type is CHUNK_ITEM_KEY, but struct is %T\n",
- nodeRef.Addr, i, item.Body)
- continue
+ for _, dev := range fs.Devices {
+ fmt.Printf("Pass 1: ... dev[%q] scanning for nodes\n", dev.Name())
+ foundNodes := make(map[btrfs.LogicalAddr][]btrfs.PhysicalAddr)
+ var lostAndFoundChunks []btrfs.SysChunk
+ if err := btrfsmisc.ScanForNodes(dev, superblock.Data, func(nodeRef *util.Ref[btrfs.PhysicalAddr, btrfs.Node], err error) {
+ if err != nil {
+ fmt.Printf("Pass 1: ... dev[%q] error: %v\n", dev.Name(), err)
+ return
+ }
+ foundNodes[nodeRef.Data.Head.Addr] = append(foundNodes[nodeRef.Data.Head.Addr], nodeRef.Addr)
+ _, alreadyVisited := visitedChunkNodes[nodeRef.Data.Head.Addr]
+ if nodeRef.Data.Head.Owner == btrfs.CHUNK_TREE_OBJECTID && !alreadyVisited {
+ for i, item := range nodeRef.Data.BodyLeaf {
+ if item.Head.Key.ItemType != btrfsitem.CHUNK_ITEM_KEY {
+ continue
+ }
+ chunk, ok := item.Body.(btrfsitem.Chunk)
+ if !ok {
+ fmt.Printf("Pass 1: ... dev[%q] node@%d: item %d: error: type is CHUNK_ITEM_KEY, but struct is %T\n",
+ dev.Name(), nodeRef.Addr, i, item.Body)
+ continue
+ }
+ fmt.Printf("Pass 1: ... dev[%q] node@%d: item %d: found chunk\n",
+ dev.Name(), nodeRef.Addr, i)
+ lostAndFoundChunks = append(lostAndFoundChunks, btrfs.SysChunk{
+ Key: item.Head.Key,
+ Chunk: chunk,
+ })
}
- fmt.Printf("Pass 1: node@%d: item %d: found chunk\n",
- nodeRef.Addr, i)
- lostAndFoundChunks = append(lostAndFoundChunks, btrfs.SysChunk{
- Key: item.Head.Key,
- Chunk: chunk,
- })
}
+ }); err != nil {
+ return err
}
- }); err != nil {
- return err
- }
- fmt.Printf("Pass 1: ... re-inserting lost+found chunks\n")
- if len(lostAndFoundChunks) > 0 {
- panic("TODO")
- }
+ fmt.Printf("Pass 1: ... dev[%q] re-inserting lost+found chunks\n", dev.Name())
+ if len(lostAndFoundChunks) > 0 {
+ panic("TODO")
+ }
- fmt.Printf("Pass 1: ... re-constructing stripes for lost+found nodes\n")
- lostAndFoundNodes := make(map[btrfs.PhysicalAddr]btrfs.LogicalAddr)
- for laddr, readPaddrs := range foundNodes {
- resolvedPaddrs, _ := fs.Resolve(laddr)
- for _, readPaddr := range readPaddrs {
- if _, ok := resolvedPaddrs[btrfs.QualifiedPhysicalAddr{
- Dev: superblock.Data.DevItem.DevUUID,
- Addr: readPaddr,
- }]; !ok {
- lostAndFoundNodes[readPaddr] = laddr
+ fmt.Printf("Pass 1: ... dev[%q] re-constructing stripes for lost+found nodes\n", dev.Name())
+ lostAndFoundNodes := make(map[btrfs.PhysicalAddr]btrfs.LogicalAddr)
+ for laddr, readPaddrs := range foundNodes {
+ resolvedPaddrs, _ := fs.Resolve(laddr)
+ for _, readPaddr := range readPaddrs {
+ if _, ok := resolvedPaddrs[btrfs.QualifiedPhysicalAddr{
+ Dev: superblock.Data.DevItem.DevUUID,
+ Addr: readPaddr,
+ }]; !ok {
+ lostAndFoundNodes[readPaddr] = laddr
+ }
}
}
- }
- sortedPaddrs := make([]btrfs.PhysicalAddr, 0, len(lostAndFoundNodes))
- for paddr := range lostAndFoundNodes {
- sortedPaddrs = append(sortedPaddrs, paddr)
- }
- sort.Slice(sortedPaddrs, func(i, j int) bool {
- return sortedPaddrs[i] < sortedPaddrs[j]
- })
- type stripe struct {
- PAddr btrfs.PhysicalAddr
- LAddr btrfs.LogicalAddr
- Size uint64
- }
- var stripes []stripe
- for _, paddr := range sortedPaddrs {
- var lastStripe *stripe
- if len(stripes) > 0 {
- lastStripe = &stripes[len(stripes)-1]
+ sortedPaddrs := make([]btrfs.PhysicalAddr, 0, len(lostAndFoundNodes))
+ for paddr := range lostAndFoundNodes {
+ sortedPaddrs = append(sortedPaddrs, paddr)
}
- if lastStripe != nil && (lastStripe.PAddr+btrfs.PhysicalAddr(lastStripe.Size)) == paddr {
- lastStripe.Size += uint64(superblock.Data.NodeSize)
- } else {
- stripes = append(stripes, stripe{
- PAddr: paddr,
- LAddr: lostAndFoundNodes[paddr],
- Size: uint64(superblock.Data.NodeSize),
- })
+ sort.Slice(sortedPaddrs, func(i, j int) bool {
+ return sortedPaddrs[i] < sortedPaddrs[j]
+ })
+ type stripe struct {
+ PAddr btrfs.PhysicalAddr
+ LAddr btrfs.LogicalAddr
+ Size uint64
+ }
+ var stripes []stripe
+ for _, paddr := range sortedPaddrs {
+ var lastStripe *stripe
+ if len(stripes) > 0 {
+ lastStripe = &stripes[len(stripes)-1]
+ }
+ if lastStripe != nil && (lastStripe.PAddr+btrfs.PhysicalAddr(lastStripe.Size)) == paddr {
+ lastStripe.Size += uint64(superblock.Data.NodeSize)
+ } else {
+ stripes = append(stripes, stripe{
+ PAddr: paddr,
+ LAddr: lostAndFoundNodes[paddr],
+ Size: uint64(superblock.Data.NodeSize),
+ })
+ }
}
+ fmt.Printf("Pass 1: ... dev[%q] reconstructed stripes: %#v\n", dev.Name(), stripes)
}
- fmt.Printf("Pass 1: ... reconstructed stripes: %#v\n", stripes)
fmt.Printf("\nPass 2: ?????????????????????????\n") ////////////////////////////////////////
/*