summaryrefslogtreecommitdiff
path: root/pkg
diff options
context:
space:
mode:
Diffstat (limited to 'pkg')
-rw-r--r--pkg/btrfs/btrfsitem/item_chunk.go6
-rw-r--r--pkg/btrfs/io2_fs.go2
-rw-r--r--pkg/btrfs/types_btree.go42
-rw-r--r--pkg/btrfsmisc/fsck.go2
4 files changed, 47 insertions, 5 deletions
diff --git a/pkg/btrfs/btrfsitem/item_chunk.go b/pkg/btrfs/btrfsitem/item_chunk.go
index eae8339..4389a46 100644
--- a/pkg/btrfs/btrfsitem/item_chunk.go
+++ b/pkg/btrfs/btrfsitem/item_chunk.go
@@ -23,9 +23,9 @@ type Chunk struct { // CHUNK_ITEM=228
}
type ChunkStripe struct {
- DeviceID internal.ObjID `bin:"off=0x0, siz=0x8"`
- Offset uint64 `bin:"off=0x8, siz=0x8"`
- DeviceUUID internal.UUID `bin:"off=0x10, siz=0x10"`
+ DeviceID internal.ObjID `bin:"off=0x0, siz=0x8"`
+ Offset internal.PhysicalAddr `bin:"off=0x8, siz=0x8"`
+ DeviceUUID internal.UUID `bin:"off=0x10, siz=0x10"`
binstruct.End `bin:"off=0x20"`
}
diff --git a/pkg/btrfs/io2_fs.go b/pkg/btrfs/io2_fs.go
index ff5415a..ca67a9c 100644
--- a/pkg/btrfs/io2_fs.go
+++ b/pkg/btrfs/io2_fs.go
@@ -181,7 +181,7 @@ func (fs *FS) Resolve(laddr LogicalAddr) (paddrs map[QualifiedPhysicalAddr]struc
for _, stripe := range chunk.Chunk.Stripes {
paddrs[QualifiedPhysicalAddr{
Dev: stripe.DeviceUUID,
- Addr: PhysicalAddr(stripe.Offset + offsetWithinChunk),
+ Addr: stripe.Offset + PhysicalAddr(offsetWithinChunk),
}] = struct{}{}
}
}
diff --git a/pkg/btrfs/types_btree.go b/pkg/btrfs/types_btree.go
index 5adc7ec..89901c3 100644
--- a/pkg/btrfs/types_btree.go
+++ b/pkg/btrfs/types_btree.go
@@ -2,7 +2,9 @@ package btrfs
import (
"encoding/binary"
+ "errors"
"fmt"
+ iofs "io/fs"
"lukeshu.com/btrfs-tools/pkg/binstruct"
"lukeshu.com/btrfs-tools/pkg/btrfs/btrfsitem"
@@ -297,6 +299,10 @@ func (fs *FS) ReadNode(addr LogicalAddr) (*util.Ref[LogicalAddr, Node], error) {
}
type WalkTreeHandler struct {
+ // Callbacks for entire nodes
+ PreNode func(LogicalAddr) error
+ MidNode func(*util.Ref[LogicalAddr, Node]) error
+ PostNode func(*util.Ref[LogicalAddr, Node]) error
// Callbacks for items on internal nodes
PreKeyPointer func(KeyPointer) error
PostKeyPointer func(KeyPointer) error
@@ -310,18 +316,40 @@ func (fs *FS) WalkTree(nodeAddr LogicalAddr, cbs WalkTreeHandler) error {
if nodeAddr == 0 {
return nil
}
+ if cbs.PreNode != nil {
+ if err := cbs.PreNode(nodeAddr); err != nil {
+ if errors.Is(err, iofs.SkipDir) {
+ return nil
+ }
+ return err
+ }
+ }
node, err := fs.ReadNode(nodeAddr)
if err != nil {
if cbs.NodeError != nil {
err = cbs.NodeError(err)
}
if err != nil {
+ if errors.Is(err, iofs.SkipDir) {
+ return nil
+ }
return fmt.Errorf("btrfs.FS.WalkTree: %w", err)
}
}
+ if cbs.MidNode != nil {
+ if err := cbs.MidNode(node); err != nil {
+ if errors.Is(err, iofs.SkipDir) {
+ return nil
+ }
+ return 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
+ }
return err
}
}
@@ -330,6 +358,9 @@ func (fs *FS) WalkTree(nodeAddr LogicalAddr, cbs WalkTreeHandler) error {
}
if cbs.PostKeyPointer != nil {
if err := cbs.PostKeyPointer(item); err != nil {
+ if errors.Is(err, iofs.SkipDir) {
+ continue
+ }
return err
}
}
@@ -337,9 +368,20 @@ func (fs *FS) WalkTree(nodeAddr LogicalAddr, cbs WalkTreeHandler) error {
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)
}
}
}
+ if cbs.PostNode != nil {
+ if err := cbs.PostNode(node); err != nil {
+ if errors.Is(err, iofs.SkipDir) {
+ return nil
+ }
+ return err
+ }
+ }
return nil
}
diff --git a/pkg/btrfsmisc/fsck.go b/pkg/btrfsmisc/fsck.go
index a9e7d1d..8d20e6e 100644
--- a/pkg/btrfsmisc/fsck.go
+++ b/pkg/btrfsmisc/fsck.go
@@ -23,7 +23,7 @@ func ScanForNodes(dev *btrfs.Device, sb btrfs.Superblock, fn func(*util.Ref[btrf
}
nodeBuf := make([]byte, sb.NodeSize)
- for pos := btrfs.PhysicalAddr(0); pos+btrfs.PhysicalAddr(sb.SectorSize) < devSize; pos += btrfs.PhysicalAddr(sb.SectorSize) {
+ for pos := btrfs.PhysicalAddr(0); pos+btrfs.PhysicalAddr(sb.NodeSize) < devSize; pos += btrfs.PhysicalAddr(sb.SectorSize) {
if util.InSlice(pos, btrfs.SuperblockAddrs) {
//fmt.Printf("sector@%d is a superblock\n", pos)
continue