diff options
author | Luke Shumaker <lukeshu@lukeshu.com> | 2022-06-05 16:46:34 -0600 |
---|---|---|
committer | Luke Shumaker <lukeshu@lukeshu.com> | 2022-06-05 16:46:34 -0600 |
commit | 74b109b0a75ae6648f9381252d8beb5ce6025df3 (patch) | |
tree | 64b8b2250c67f749566761bab56676bed9c33846 /pkg/btrfs | |
parent | e134a9fbd0d8ae43e2d24c5aabad8bf6a16190ed (diff) |
factor out a btrfsmisc pacage
Diffstat (limited to 'pkg/btrfs')
-rw-r--r-- | pkg/btrfs/fsck.go | 52 | ||||
-rw-r--r-- | pkg/btrfs/io1_device.go | 7 | ||||
-rw-r--r-- | pkg/btrfs/types_btree.go | 10 | ||||
-rw-r--r-- | pkg/btrfs/util.go | 28 |
4 files changed, 9 insertions, 88 deletions
diff --git a/pkg/btrfs/fsck.go b/pkg/btrfs/fsck.go deleted file mode 100644 index 33ccd44..0000000 --- a/pkg/btrfs/fsck.go +++ /dev/null @@ -1,52 +0,0 @@ -package btrfs - -import ( - "fmt" - - "lukeshu.com/btrfs-tools/pkg/binstruct" -) - -// ScanForNodes mimics btrfs-progs -// cmds/rescue-chunk-recover.c:scan_one_device(), except it doesn't do -// anything but log when it finds a node. -func ScanForNodes(dev *Device, sb Superblock) error { - devSize, err := dev.Size() - if err != nil { - return err - } - - if sb.NodeSize < sb.SectorSize { - return fmt.Errorf("node_size(%d) < sector_size(%d)", - sb.NodeSize, sb.SectorSize) - } - - nodeBuf := make([]byte, sb.NodeSize) - for pos := PhysicalAddr(0); pos+PhysicalAddr(sb.SectorSize) < devSize; pos += PhysicalAddr(sb.SectorSize) { - if inSlice(pos, superblockAddrs) { - fmt.Printf("sector@%d is a superblock\n", pos) - continue - } - if _, err := dev.ReadAt(nodeBuf, pos); err != nil { - return fmt.Errorf("sector@%d: %w", pos, err) - } - var nodeHeader NodeHeader - if _, err := binstruct.Unmarshal(nodeBuf, &nodeHeader); err != nil { - return fmt.Errorf("sector@%d: %w", pos, err) - } - if !nodeHeader.MetadataUUID.Equal(sb.EffectiveMetadataUUID()) { - //fmt.Printf("sector@%d does not look like a node\n", pos) - continue - } - if !nodeHeader.Checksum.Equal(CRC32c(nodeBuf[0x20:])) { - fmt.Printf("sector@%d looks like a node but is corrupt (checksum doesn't match)\n", pos) - continue - } - - fmt.Printf("node@%d: physical_addr=0x%0X logical_addr=0x%0X generation=%d owner=%v level=%d\n", - pos, pos, nodeHeader.Addr, nodeHeader.Generation, nodeHeader.Owner, nodeHeader.Level) - - pos += PhysicalAddr(sb.NodeSize) - PhysicalAddr(sb.SectorSize) - } - - return nil -} diff --git a/pkg/btrfs/io1_device.go b/pkg/btrfs/io1_device.go index efd8cb9..55b7525 100644 --- a/pkg/btrfs/io1_device.go +++ b/pkg/btrfs/io1_device.go @@ -4,6 +4,7 @@ import ( "fmt" "os" + "lukeshu.com/btrfs-tools/pkg/binstruct" "lukeshu.com/btrfs-tools/pkg/util" ) @@ -19,7 +20,7 @@ func (dev Device) Size() (PhysicalAddr, error) { return PhysicalAddr(fi.Size()), nil } -var superblockAddrs = []PhysicalAddr{ +var SuperblockAddrs = []PhysicalAddr{ 0x00_0001_0000, // 64KiB 0x00_0400_0000, // 64MiB 0x40_0000_0000, // 256GiB @@ -30,7 +31,7 @@ func (dev *Device) ReadAt(dat []byte, paddr PhysicalAddr) (int, error) { } func (dev *Device) Superblocks() ([]util.Ref[PhysicalAddr, Superblock], error) { - const superblockSize = 0x1000 + superblockSize := PhysicalAddr(binstruct.StaticSize(Superblock{})) sz, err := dev.Size() if err != nil { @@ -38,7 +39,7 @@ func (dev *Device) Superblocks() ([]util.Ref[PhysicalAddr, Superblock], error) { } var ret []util.Ref[PhysicalAddr, Superblock] - for i, addr := range superblockAddrs { + for i, addr := range SuperblockAddrs { if addr+superblockSize <= sz { superblock := util.Ref[PhysicalAddr, Superblock]{ File: dev, diff --git a/pkg/btrfs/types_btree.go b/pkg/btrfs/types_btree.go index d65e599..96b069a 100644 --- a/pkg/btrfs/types_btree.go +++ b/pkg/btrfs/types_btree.go @@ -137,18 +137,18 @@ func (node *Node) UnmarshalBinary(nodeBuf []byte) (int, error) { dataOff := binstruct.StaticSize(NodeHeader{}) + int(item.Head.DataOffset) dataSize := int(item.Head.DataSize) if dataOff+dataSize > len(nodeBuf) { - return max(n, lastRead), fmt.Errorf("(leaf): item references byte %d, but node only has %d bytes", + return util.Max(n, lastRead), fmt.Errorf("(leaf): item references byte %d, but node only has %d bytes", dataOff+dataSize, len(nodeBuf)) } dataBuf := nodeBuf[dataOff : dataOff+dataSize] - firstRead = min(firstRead, dataOff) - lastRead = max(lastRead, dataOff+dataSize) + firstRead = util.Min(firstRead, dataOff) + lastRead = util.Max(lastRead, dataOff+dataSize) item.Body = btrfsitem.UnmarshalItem(item.Head.Key, dataBuf) node.BodyLeaf = append(node.BodyLeaf, item) } node.Padding = nodeBuf[n:firstRead] - return max(n, lastRead), nil + return util.Max(n, lastRead), nil } } @@ -201,7 +201,7 @@ func (node Node) MarshalBinary() ([]byte, error) { return ret, err } dataOff := binstruct.StaticSize(NodeHeader{}) + int(item.Head.DataOffset) - minData = min(minData, dataOff) + minData = util.Min(minData, dataOff) if copy(ret[dataOff:], dat) < len(dat) { return ret, fmt.Errorf("btrfs.Node.MarshalBinary: need at least %d bytes, but .Size is only %d", dataOff+len(dat), node.Size) diff --git a/pkg/btrfs/util.go b/pkg/btrfs/util.go deleted file mode 100644 index 671d6fc..0000000 --- a/pkg/btrfs/util.go +++ /dev/null @@ -1,28 +0,0 @@ -package btrfs - -import ( - "golang.org/x/exp/constraints" -) - -func inSlice[T comparable](needle T, haystack []T) bool { - for _, straw := range haystack { - if needle == straw { - return true - } - } - return false -} - -func max[T constraints.Ordered](a, b T) T { - if a > b { - return a - } - return b -} - -func min[T constraints.Ordered](a, b T) T { - if a < b { - return a - } - return b -} |