summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@lukeshu.com>2022-06-06 23:56:11 -0600
committerLuke Shumaker <lukeshu@lukeshu.com>2022-06-06 23:56:11 -0600
commit69f0420fdb3701fd6ed6a682835e3ba282b7bdbb (patch)
tree2a48cfd35792fb3dca803f2982a9cb0f7a03c03c
parent07b7c8a2a12a09c49659efbe522ad1c3f7161aed (diff)
fixup
-rw-r--r--cmd/btrfs-fsck/pass1.go24
-rw-r--r--pkg/btrfs/crc32c.go2
-rw-r--r--pkg/btrfs/types_btree.go48
3 files changed, 46 insertions, 28 deletions
diff --git a/cmd/btrfs-fsck/pass1.go b/cmd/btrfs-fsck/pass1.go
index 97129cd..378c88d 100644
--- a/cmd/btrfs-fsck/pass1.go
+++ b/cmd/btrfs-fsck/pass1.go
@@ -170,16 +170,16 @@ func pass1ReconstructChunksOneDev(
LAddr btrfs.LogicalAddr
Size uint64
}
- var stripes []stripe
+ var stripes []*stripe
for _, paddr := range sortedPaddrs {
var lastStripe *stripe
if len(stripes) > 0 {
- lastStripe = &stripes[len(stripes)-1]
+ 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{
+ stripes = append(stripes, &stripe{
PAddr: paddr,
LAddr: lostAndFoundNodes[paddr],
Size: uint64(superblock.Data.NodeSize),
@@ -242,6 +242,7 @@ func pass1WriteReconstructedChunks(
},
},
}
+
for _, dev := range fs.Devices {
superblock, _ := dev.Superblock()
reconstructedNode.Data.BodyLeaf = append(reconstructedNode.Data.BodyLeaf, btrfs.Item{
@@ -255,7 +256,20 @@ func pass1WriteReconstructedChunks(
Body: superblock.Data.DevItem,
})
}
- for laddr, chunk := range fsReconstructedChunks {
+
+ sortedLAddrs := make([]btrfs.LogicalAddr, 0, len(fsReconstructedChunks))
+ for laddr := range fsReconstructedChunks {
+ sortedLAddrs = append(sortedLAddrs, laddr)
+ }
+ sort.Slice(sortedLAddrs, func(i, j int) bool {
+ return sortedLAddrs[i] < sortedLAddrs[j]
+ })
+ for i, laddr := range sortedLAddrs {
+ chunk := fsReconstructedChunks[laddr]
+ for j, stripe := range chunk.Stripes {
+ fmt.Printf("Pass 1: chunk[%d].stripe[%d] = { laddr=0x%0x ⇒ { dev_id=%v, paddr=0x%0x }, size=0x%0x }\n",
+ i, j, laddr, stripe.DeviceID, stripe.Offset, chunk.Size)
+ }
reconstructedNode.Data.BodyLeaf = append(reconstructedNode.Data.BodyLeaf, btrfs.Item{
Head: btrfs.ItemHeader{
Key: btrfs.Key{
@@ -280,11 +294,13 @@ func pass1WriteReconstructedChunks(
},
})
}
+
var err error
reconstructedNode.Data.Head.Checksum, err = reconstructedNode.Data.CalculateChecksum()
if err != nil {
fmt.Printf("Pass 1: ... new node checksum: error: %v\n", err)
}
+
if err := reconstructedNode.Write(); err != nil {
fmt.Printf("Pass 1: ... write new node: error: %v\n", err)
}
diff --git a/pkg/btrfs/crc32c.go b/pkg/btrfs/crc32c.go
index 8266706..ab2d6e9 100644
--- a/pkg/btrfs/crc32c.go
+++ b/pkg/btrfs/crc32c.go
@@ -9,7 +9,7 @@ import (
type CSum [0x20]byte
func (csum CSum) String() string {
- return fmt.Sprintf("%x", csum)
+ return fmt.Sprintf("%x", [0x20]byte(csum))
}
func CRC32c(data []byte) CSum {
diff --git a/pkg/btrfs/types_btree.go b/pkg/btrfs/types_btree.go
index f72be96..734c859 100644
--- a/pkg/btrfs/types_btree.go
+++ b/pkg/btrfs/types_btree.go
@@ -204,7 +204,7 @@ func (node *Node) marshalInternalTo(bodyBuf []byte) error {
}
if copy(bodyBuf[n:], bs) < len(bs) {
return fmt.Errorf("item %d: not enough space: need at least %d+%d=%d bytes, but only have %d",
- n, len(bs), n+len(bs), len(bodyBuf))
+ i, n, len(bs), n+len(bs), len(bodyBuf))
}
n += len(bs)
}
@@ -346,7 +346,7 @@ func ReadNode[Addr ~int64](fs util.File[Addr], sb Superblock, addr Addr, laddrCB
if laddrCB != nil {
if err := laddrCB(nodeRef.Data.Head.Addr); err != nil {
- return nodeRef, fmt.Errorf("btrfs.ReadNode: node@%d: %w", err)
+ return nodeRef, fmt.Errorf("btrfs.ReadNode: node@%d: %w", addr, err)
}
}
@@ -410,34 +410,36 @@ func (fs *FS) WalkTree(nodeAddr LogicalAddr, cbs WalkTreeHandler) error {
}
return fmt.Errorf("btrfs.FS.WalkTree: %w", err)
}
- for _, item := range node.Data.BodyInternal {
- if cbs.PreKeyPointer != nil {
- if err := cbs.PreKeyPointer(item); err != nil {
- if errors.Is(err, iofs.SkipDir) {
- continue
+ if node != nil {
+ for _, item := range node.Data.BodyInternal {
+ if cbs.PreKeyPointer != nil {
+ if err := cbs.PreKeyPointer(item); err != nil {
+ if errors.Is(err, iofs.SkipDir) {
+ continue
+ }
+ return err
}
+ }
+ if err := fs.WalkTree(item.BlockPtr, cbs); err != nil {
return err
}
- }
- if err := fs.WalkTree(item.BlockPtr, cbs); err != nil {
- return err
- }
- if cbs.PostKeyPointer != nil {
- if err := cbs.PostKeyPointer(item); err != nil {
- if errors.Is(err, iofs.SkipDir) {
- continue
+ if cbs.PostKeyPointer != nil {
+ if err := cbs.PostKeyPointer(item); err != nil {
+ if errors.Is(err, iofs.SkipDir) {
+ continue
+ }
+ return err
}
- return err
}
}
- }
- for _, item := range node.Data.BodyLeaf {
- if cbs.Item != nil {
- if err := cbs.Item(item.Head.Key, item.Body); err != nil {
- if errors.Is(err, iofs.SkipDir) {
- continue
+ for _, item := range node.Data.BodyLeaf {
+ if cbs.Item != nil {
+ if err := cbs.Item(item.Head.Key, item.Body); err != nil {
+ if errors.Is(err, iofs.SkipDir) {
+ continue
+ }
+ return fmt.Errorf("btrfs.FS.WalkTree: callback: %w", err)
}
- return fmt.Errorf("btrfs.FS.WalkTree: callback: %w", err)
}
}
}