diff options
Diffstat (limited to 'pkg/btrfs')
-rw-r--r-- | pkg/btrfs/aliases.go | 15 | ||||
-rw-r--r-- | pkg/btrfs/btrfssum/csum.go (renamed from pkg/btrfs/csum.go) | 34 | ||||
-rw-r--r-- | pkg/btrfs/btrfssum/csum_test.go (renamed from pkg/btrfs/csum_test.go) | 10 | ||||
-rw-r--r-- | pkg/btrfs/io1_pv.go (renamed from pkg/btrfs/io1_device.go) | 27 | ||||
-rw-r--r-- | pkg/btrfs/io2_lv.go (renamed from pkg/btrfs/io2_fs.go) | 27 | ||||
-rw-r--r-- | pkg/btrfs/io3_btree.go (renamed from pkg/btrfs/btree.go) | 21 | ||||
-rw-r--r-- | pkg/btrfs/types_node.go (renamed from pkg/btrfs/types_btree.go) | 48 | ||||
-rw-r--r-- | pkg/btrfs/types_superblock.go | 46 |
8 files changed, 115 insertions, 113 deletions
diff --git a/pkg/btrfs/aliases.go b/pkg/btrfs/aliases.go index 22508c3..1a18ae6 100644 --- a/pkg/btrfs/aliases.go +++ b/pkg/btrfs/aliases.go @@ -1,7 +1,6 @@ package btrfs import ( - "lukeshu.com/btrfs-tools/pkg/btrfs/btrfsvol" "lukeshu.com/btrfs-tools/pkg/btrfs/internal" "lukeshu.com/btrfs-tools/pkg/util" ) @@ -9,16 +8,12 @@ import ( type ( // (u)int64 types - Generation = internal.Generation - ObjID = internal.ObjID - LogicalAddr = btrfsvol.LogicalAddr - PhysicalAddr = btrfsvol.PhysicalAddr - AddrDelta = btrfsvol.AddrDelta + Generation = internal.Generation + ObjID = internal.ObjID // complex types - Key = internal.Key - Time = internal.Time - UUID = util.UUID - QualifiedPhysicalAddr = btrfsvol.QualifiedPhysicalAddr + Key = internal.Key + Time = internal.Time + UUID = util.UUID ) diff --git a/pkg/btrfs/csum.go b/pkg/btrfs/btrfssum/csum.go index 6245fa4..22d8149 100644 --- a/pkg/btrfs/csum.go +++ b/pkg/btrfs/btrfssum/csum.go @@ -1,4 +1,4 @@ -package btrfs +package btrfssum import ( "encoding/binary" @@ -26,18 +26,18 @@ func (csum CSum) Format(f fmt.State, verb rune) { type CSumType uint16 const ( - CSUM_TYPE_CRC32 = CSumType(iota) - CSUM_TYPE_XXHASH - CSUM_TYPE_SHA256 - CSUM_TYPE_BLAKE2 + TYPE_CRC32 = CSumType(iota) + TYPE_XXHASH + TYPE_SHA256 + TYPE_BLAKE2 ) func (typ CSumType) String() string { names := map[CSumType]string{ - CSUM_TYPE_CRC32: "crc32c", - CSUM_TYPE_XXHASH: "xxhash64", - CSUM_TYPE_SHA256: "sha256", - CSUM_TYPE_BLAKE2: "blake2", + TYPE_CRC32: "crc32c", + TYPE_XXHASH: "xxhash64", + TYPE_SHA256: "sha256", + TYPE_BLAKE2: "blake2", } if name, ok := names[typ]; ok { return name @@ -47,10 +47,10 @@ func (typ CSumType) String() string { func (typ CSumType) Size() int { sizes := map[CSumType]int{ - CSUM_TYPE_CRC32: 4, - CSUM_TYPE_XXHASH: 8, - CSUM_TYPE_SHA256: 32, - CSUM_TYPE_BLAKE2: 32, + TYPE_CRC32: 4, + TYPE_XXHASH: 8, + TYPE_SHA256: 32, + TYPE_BLAKE2: 32, } if size, ok := sizes[typ]; ok { return size @@ -60,17 +60,17 @@ func (typ CSumType) Size() int { func (typ CSumType) Sum(data []byte) (CSum, error) { switch typ { - case CSUM_TYPE_CRC32: + case TYPE_CRC32: crc := crc32.Update(0, crc32.MakeTable(crc32.Castagnoli), data) var ret CSum binary.LittleEndian.PutUint32(ret[:], crc) return ret, nil - case CSUM_TYPE_XXHASH: + case TYPE_XXHASH: panic("not implemented") - case CSUM_TYPE_SHA256: + case TYPE_SHA256: panic("not implemented") - case CSUM_TYPE_BLAKE2: + case TYPE_BLAKE2: panic("not implemented") default: return CSum{}, fmt.Errorf("unknown checksum type: %v", typ) diff --git a/pkg/btrfs/csum_test.go b/pkg/btrfs/btrfssum/csum_test.go index 8c2d544..c47409c 100644 --- a/pkg/btrfs/csum_test.go +++ b/pkg/btrfs/btrfssum/csum_test.go @@ -1,4 +1,4 @@ -package btrfs_test +package btrfssum_test import ( "fmt" @@ -6,23 +6,23 @@ import ( "github.com/stretchr/testify/assert" - "lukeshu.com/btrfs-tools/pkg/btrfs" + "lukeshu.com/btrfs-tools/pkg/btrfs/btrfssum" ) func TestCSumFormat(t *testing.T) { t.Parallel() type TestCase struct { - InputSum btrfs.CSum + InputSum btrfssum.CSum InputFmt string Output string } - csum := btrfs.CSum{0xbd, 0x7b, 0x41, 0xf4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0} + csum := btrfssum.CSum{0xbd, 0x7b, 0x41, 0xf4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0} testcases := map[string]TestCase{ "s": {InputSum: csum, InputFmt: "%s", Output: "bd7b41f400000000000000000000000000000000000000000000000000000000"}, "x": {InputSum: csum, InputFmt: "%x", Output: "bd7b41f400000000000000000000000000000000000000000000000000000000"}, "v": {InputSum: csum, InputFmt: "%v", Output: "bd7b41f400000000000000000000000000000000000000000000000000000000"}, "70s": {InputSum: csum, InputFmt: "|% 70s", Output: "| bd7b41f400000000000000000000000000000000000000000000000000000000"}, - "#180v": {InputSum: csum, InputFmt: "%#180v", Output: " btrfs.CSum{0xbd, 0x7b, 0x41, 0xf4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}"}, + "#180v": {InputSum: csum, InputFmt: "%#180v", Output: " btrfssum.CSum{0xbd, 0x7b, 0x41, 0xf4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}"}, } for tcName, tc := range testcases { tc := tc diff --git a/pkg/btrfs/io1_device.go b/pkg/btrfs/io1_pv.go index 29af11c..b9f7ea4 100644 --- a/pkg/btrfs/io1_device.go +++ b/pkg/btrfs/io1_pv.go @@ -5,55 +5,56 @@ import ( "os" "lukeshu.com/btrfs-tools/pkg/binstruct" + "lukeshu.com/btrfs-tools/pkg/btrfs/btrfsvol" "lukeshu.com/btrfs-tools/pkg/util" ) type Device struct { *os.File - cacheSuperblocks []*util.Ref[PhysicalAddr, Superblock] - cacheSuperblock *util.Ref[PhysicalAddr, Superblock] + cacheSuperblocks []*util.Ref[btrfsvol.PhysicalAddr, Superblock] + cacheSuperblock *util.Ref[btrfsvol.PhysicalAddr, Superblock] } -var _ util.File[PhysicalAddr] = (*Device)(nil) +var _ util.File[btrfsvol.PhysicalAddr] = (*Device)(nil) -func (dev Device) Size() (PhysicalAddr, error) { +func (dev Device) Size() (btrfsvol.PhysicalAddr, error) { fi, err := dev.Stat() if err != nil { return 0, err } - return PhysicalAddr(fi.Size()), nil + return btrfsvol.PhysicalAddr(fi.Size()), nil } -func (dev *Device) ReadAt(dat []byte, paddr PhysicalAddr) (int, error) { +func (dev *Device) ReadAt(dat []byte, paddr btrfsvol.PhysicalAddr) (int, error) { return dev.File.ReadAt(dat, int64(paddr)) } -func (dev *Device) WriteAt(dat []byte, paddr PhysicalAddr) (int, error) { +func (dev *Device) WriteAt(dat []byte, paddr btrfsvol.PhysicalAddr) (int, error) { return dev.File.WriteAt(dat, int64(paddr)) } -var SuperblockAddrs = []PhysicalAddr{ +var SuperblockAddrs = []btrfsvol.PhysicalAddr{ 0x00_0001_0000, // 64KiB 0x00_0400_0000, // 64MiB 0x40_0000_0000, // 256GiB } -func (dev *Device) Superblocks() ([]*util.Ref[PhysicalAddr, Superblock], error) { +func (dev *Device) Superblocks() ([]*util.Ref[btrfsvol.PhysicalAddr, Superblock], error) { if dev.cacheSuperblocks != nil { return dev.cacheSuperblocks, nil } - superblockSize := PhysicalAddr(binstruct.StaticSize(Superblock{})) + superblockSize := btrfsvol.PhysicalAddr(binstruct.StaticSize(Superblock{})) sz, err := dev.Size() if err != nil { return nil, err } - var ret []*util.Ref[PhysicalAddr, Superblock] + var ret []*util.Ref[btrfsvol.PhysicalAddr, Superblock] for i, addr := range SuperblockAddrs { if addr+superblockSize <= sz { - superblock := &util.Ref[PhysicalAddr, Superblock]{ + superblock := &util.Ref[btrfsvol.PhysicalAddr, Superblock]{ File: dev, Addr: addr, } @@ -70,7 +71,7 @@ func (dev *Device) Superblocks() ([]*util.Ref[PhysicalAddr, Superblock], error) return ret, nil } -func (dev *Device) Superblock() (*util.Ref[PhysicalAddr, Superblock], error) { +func (dev *Device) Superblock() (*util.Ref[btrfsvol.PhysicalAddr, Superblock], error) { if dev.cacheSuperblock != nil { return dev.cacheSuperblock, nil } diff --git a/pkg/btrfs/io2_fs.go b/pkg/btrfs/io2_lv.go index 5129329..0564066 100644 --- a/pkg/btrfs/io2_fs.go +++ b/pkg/btrfs/io2_lv.go @@ -16,11 +16,11 @@ type FS struct { // implementing special things like fsck. LV btrfsvol.LogicalVolume[*Device] - cacheSuperblocks []*util.Ref[PhysicalAddr, Superblock] - cacheSuperblock *util.Ref[PhysicalAddr, Superblock] + cacheSuperblocks []*util.Ref[btrfsvol.PhysicalAddr, Superblock] + cacheSuperblock *util.Ref[btrfsvol.PhysicalAddr, Superblock] } -var _ util.File[LogicalAddr] = (*FS)(nil) +var _ util.File[btrfsvol.LogicalAddr] = (*FS)(nil) func (fs *FS) AddDevice(dev *Device) error { sb, err := dev.Superblock() @@ -51,26 +51,26 @@ func (fs *FS) Name() string { return name } -func (fs *FS) Size() (LogicalAddr, error) { +func (fs *FS) Size() (btrfsvol.LogicalAddr, error) { return fs.LV.Size() } -func (fs *FS) ReadAt(p []byte, off LogicalAddr) (int, error) { +func (fs *FS) ReadAt(p []byte, off btrfsvol.LogicalAddr) (int, error) { return fs.LV.ReadAt(p, off) } -func (fs *FS) WriteAt(p []byte, off LogicalAddr) (int, error) { +func (fs *FS) WriteAt(p []byte, off btrfsvol.LogicalAddr) (int, error) { return fs.LV.WriteAt(p, off) } -func (fs *FS) Resolve(laddr LogicalAddr) (paddrs map[QualifiedPhysicalAddr]struct{}, maxlen AddrDelta) { +func (fs *FS) Resolve(laddr btrfsvol.LogicalAddr) (paddrs map[btrfsvol.QualifiedPhysicalAddr]struct{}, maxlen btrfsvol.AddrDelta) { return fs.LV.Resolve(laddr) } -func (fs *FS) Superblocks() ([]*util.Ref[PhysicalAddr, Superblock], error) { +func (fs *FS) Superblocks() ([]*util.Ref[btrfsvol.PhysicalAddr, Superblock], error) { if fs.cacheSuperblocks != nil { return fs.cacheSuperblocks, nil } - var ret []*util.Ref[PhysicalAddr, Superblock] + var ret []*util.Ref[btrfsvol.PhysicalAddr, Superblock] devs := fs.LV.PhysicalVolumes() if len(devs) == 0 { return nil, fmt.Errorf("no devices") @@ -86,7 +86,7 @@ func (fs *FS) Superblocks() ([]*util.Ref[PhysicalAddr, Superblock], error) { return ret, nil } -func (fs *FS) Superblock() (*util.Ref[PhysicalAddr, Superblock], error) { +func (fs *FS) Superblock() (*util.Ref[btrfsvol.PhysicalAddr, Superblock], error) { if fs.cacheSuperblock != nil { return fs.cacheSuperblock, nil } @@ -112,8 +112,9 @@ func (fs *FS) Superblock() (*util.Ref[PhysicalAddr, Superblock], error) { return nil, fmt.Errorf("file %q superblock %v: %w", sb.File.Name(), sbi, err) } if i > 0 { - // This is probably wrong, but lots of my - // multi-device code is probably wrong. + // FIXME(lukeshu): This is probably wrong, but + // lots of my multi-device code is probably + // wrong. if !sb.Data.Equal(sbs[0].Data) { return nil, fmt.Errorf("file %q superblock %v and file %q superblock %v disagree", sbs[0].File.Name(), 0, @@ -140,7 +141,7 @@ func (fs *FS) ReInit() error { return nil } -func (fs *FS) initDev(sb *util.Ref[PhysicalAddr, Superblock]) error { +func (fs *FS) initDev(sb *util.Ref[btrfsvol.PhysicalAddr, Superblock]) error { syschunks, err := sb.Data.ParseSysChunkArray() if err != nil { return err diff --git a/pkg/btrfs/btree.go b/pkg/btrfs/io3_btree.go index cc68002..b4eb4cb 100644 --- a/pkg/btrfs/btree.go +++ b/pkg/btrfs/io3_btree.go @@ -10,6 +10,7 @@ import ( "github.com/datawire/dlib/derror" + "lukeshu.com/btrfs-tools/pkg/btrfs/btrfsvol" "lukeshu.com/btrfs-tools/pkg/util" ) @@ -31,7 +32,7 @@ type TreePathElem struct { // NodeAddr is the address of the node that the KeyPointer // points at, or 0 if this is a leaf item and nothing is // being pointed at. - NodeAddr LogicalAddr + NodeAddr btrfsvol.LogicalAddr // NodeLevel is the expected or actual level of the node at // NodeAddr, or 255 if there is no knowledge of the level. NodeLevel uint8 @@ -64,8 +65,8 @@ func (path TreePath) String() string { type TreeWalkHandler struct { // Callbacks for entire nodes PreNode func(TreePath) error - Node func(TreePath, *util.Ref[LogicalAddr, Node], error) error - PostNode func(TreePath, *util.Ref[LogicalAddr, Node]) error + Node func(TreePath, *util.Ref[btrfsvol.LogicalAddr, Node], error) error + PostNode func(TreePath, *util.Ref[btrfsvol.LogicalAddr, Node]) error // Callbacks for items on internal nodes PreKeyPointer func(TreePath, KeyPointer) error PostKeyPointer func(TreePath, KeyPointer) error @@ -86,7 +87,7 @@ type TreeWalkHandler struct { // else: // 004 .Item() // 007 .PostNode() -func (fs *FS) TreeWalk(treeRoot LogicalAddr, cbs TreeWalkHandler) error { +func (fs *FS) TreeWalk(treeRoot btrfsvol.LogicalAddr, cbs TreeWalkHandler) error { path := TreePath{ TreePathElem{ ItemIdx: -1, @@ -175,7 +176,7 @@ func (fs *FS) treeWalk(path TreePath, cbs TreeWalkHandler) error { return nil } -func (fs *FS) treeSearch(treeRoot LogicalAddr, fn func(Key) int) (TreePath, *util.Ref[LogicalAddr, Node], error) { +func (fs *FS) treeSearch(treeRoot btrfsvol.LogicalAddr, fn func(Key) int) (TreePath, *util.Ref[btrfsvol.LogicalAddr, Node], error) { path := TreePath{ TreePathElem{ ItemIdx: -1, @@ -257,7 +258,7 @@ func (fs *FS) treeSearch(treeRoot LogicalAddr, fn func(Key) int) (TreePath, *uti } } -func (fs *FS) prev(path TreePath, node *util.Ref[LogicalAddr, Node]) (TreePath, *util.Ref[LogicalAddr, Node], error) { +func (fs *FS) prev(path TreePath, node *util.Ref[btrfsvol.LogicalAddr, Node]) (TreePath, *util.Ref[btrfsvol.LogicalAddr, Node], error) { var err error path = append(TreePath(nil), path...) @@ -309,7 +310,7 @@ func (fs *FS) prev(path TreePath, node *util.Ref[LogicalAddr, Node]) (TreePath, return path, node, nil } -func (fs *FS) next(path TreePath, node *util.Ref[LogicalAddr, Node]) (TreePath, *util.Ref[LogicalAddr, Node], error) { +func (fs *FS) next(path TreePath, node *util.Ref[btrfsvol.LogicalAddr, Node]) (TreePath, *util.Ref[btrfsvol.LogicalAddr, Node], error) { var err error path = append(TreePath(nil), path...) @@ -376,7 +377,7 @@ func (fs *FS) next(path TreePath, node *util.Ref[LogicalAddr, Node]) (TreePath, return path, node, nil } -func (fs *FS) TreeSearch(treeRoot LogicalAddr, fn func(Key) int) (Item, error) { +func (fs *FS) TreeSearch(treeRoot btrfsvol.LogicalAddr, fn func(Key) int) (Item, error) { path, node, err := fs.treeSearch(treeRoot, fn) if err != nil { return Item{}, err @@ -384,7 +385,7 @@ func (fs *FS) TreeSearch(treeRoot LogicalAddr, fn func(Key) int) (Item, error) { return node.Data.BodyLeaf[path[len(path)-1].ItemIdx], nil } -func (fs *FS) TreeLookup(treeRoot LogicalAddr, key Key) (Item, error) { +func (fs *FS) TreeLookup(treeRoot btrfsvol.LogicalAddr, key Key) (Item, error) { return fs.TreeSearch(treeRoot, key.Cmp) } @@ -392,7 +393,7 @@ func (fs *FS) TreeLookup(treeRoot LogicalAddr, key Key) (Item, error) { // return *both* a list of items and an error. // // If no such item is found, an error that is io/fs.ErrNotExist is returned. -func (fs *FS) TreeSearchAll(treeRoot LogicalAddr, fn func(Key) int) ([]Item, error) { +func (fs *FS) TreeSearchAll(treeRoot btrfsvol.LogicalAddr, fn func(Key) int) ([]Item, error) { middlePath, middleNode, err := fs.treeSearch(treeRoot, fn) if err != nil { return nil, err diff --git a/pkg/btrfs/types_btree.go b/pkg/btrfs/types_node.go index 58a08e0..24a02e5 100644 --- a/pkg/btrfs/types_btree.go +++ b/pkg/btrfs/types_node.go @@ -8,6 +8,8 @@ import ( "lukeshu.com/btrfs-tools/pkg/binstruct" "lukeshu.com/btrfs-tools/pkg/btrfs/btrfsitem" + "lukeshu.com/btrfs-tools/pkg/btrfs/btrfssum" + "lukeshu.com/btrfs-tools/pkg/btrfs/btrfsvol" "lukeshu.com/btrfs-tools/pkg/util" ) @@ -51,8 +53,8 @@ func (f NodeFlags) String() string { return util.BitfieldString(f, nodeF type Node struct { // Some context from the parent filesystem - Size uint32 // superblock.NodeSize - ChecksumType CSumType // superblock.ChecksumType + Size uint32 // superblock.NodeSize + ChecksumType btrfssum.CSumType // superblock.ChecksumType // The node's header (always present) Head NodeHeader @@ -66,16 +68,16 @@ type Node struct { } type NodeHeader struct { - Checksum CSum `bin:"off=0x0, siz=0x20"` - MetadataUUID UUID `bin:"off=0x20, siz=0x10"` - Addr LogicalAddr `bin:"off=0x30, siz=0x8"` // Logical address of this node - Flags NodeFlags `bin:"off=0x38, siz=0x7"` - BackrefRev uint8 `bin:"off=0x3f, siz=0x1"` - ChunkTreeUUID UUID `bin:"off=0x40, siz=0x10"` - Generation Generation `bin:"off=0x50, siz=0x8"` - Owner ObjID `bin:"off=0x58, siz=0x8"` // The ID of the tree that contains this node - NumItems uint32 `bin:"off=0x60, siz=0x4"` // [ignored-when-writing] - Level uint8 `bin:"off=0x64, siz=0x1"` // 0 for leaf nodes, >=1 for internal nodes + Checksum btrfssum.CSum `bin:"off=0x0, siz=0x20"` + MetadataUUID UUID `bin:"off=0x20, siz=0x10"` + Addr btrfsvol.LogicalAddr `bin:"off=0x30, siz=0x8"` // Logical address of this node + Flags NodeFlags `bin:"off=0x38, siz=0x7"` + BackrefRev uint8 `bin:"off=0x3f, siz=0x1"` + ChunkTreeUUID UUID `bin:"off=0x40, siz=0x10"` + Generation Generation `bin:"off=0x50, siz=0x8"` + Owner ObjID `bin:"off=0x58, siz=0x8"` // The ID of the tree that contains this node + NumItems uint32 `bin:"off=0x60, siz=0x4"` // [ignored-when-writing] + Level uint8 `bin:"off=0x64, siz=0x1"` // 0 for leaf nodes, >=1 for internal nodes binstruct.End `bin:"off=0x65"` } @@ -90,12 +92,12 @@ func (node Node) MaxItems() uint32 { } } -func (node Node) CalculateChecksum() (CSum, error) { +func (node Node) CalculateChecksum() (btrfssum.CSum, error) { data, err := binstruct.Marshal(node) if err != nil { - return CSum{}, err + return btrfssum.CSum{}, err } - return node.ChecksumType.Sum(data[binstruct.StaticSize(CSum{}):]) + return node.ChecksumType.Sum(data[binstruct.StaticSize(btrfssum.CSum{}):]) } func (node Node) ValidateChecksum() error { @@ -181,9 +183,9 @@ func (node Node) MarshalBinary() ([]byte, error) { // Node: "internal" //////////////////////////////////////////////////////////////////////////////// type KeyPointer struct { - Key Key `bin:"off=0x0, siz=0x11"` - BlockPtr LogicalAddr `bin:"off=0x11, siz=0x8"` - Generation Generation `bin:"off=0x19, siz=0x8"` + Key Key `bin:"off=0x0, siz=0x11"` + BlockPtr btrfsvol.LogicalAddr `bin:"off=0x11, siz=0x8"` + Generation Generation `bin:"off=0x19, siz=0x8"` binstruct.End `bin:"off=0x21"` } @@ -322,7 +324,7 @@ func (node *Node) LeafFreeSpace() uint32 { var ErrNotANode = errors.New("does not look like a node") -func ReadNode[Addr ~int64](fs util.File[Addr], sb Superblock, addr Addr, laddrCB func(LogicalAddr) error) (*util.Ref[Addr, Node], error) { +func ReadNode[Addr ~int64](fs util.File[Addr], sb Superblock, addr Addr, laddrCB func(btrfsvol.LogicalAddr) error) (*util.Ref[Addr, Node], error) { nodeBuf := make([]byte, sb.NodeSize) if _, err := fs.ReadAt(nodeBuf, addr); err != nil { return nil, err @@ -349,7 +351,7 @@ func ReadNode[Addr ~int64](fs util.File[Addr], sb Superblock, addr Addr, laddrCB } stored := nodeRef.Data.Head.Checksum - calced, err := nodeRef.Data.ChecksumType.Sum(nodeBuf[binstruct.StaticSize(CSum{}):]) + calced, err := nodeRef.Data.ChecksumType.Sum(nodeBuf[binstruct.StaticSize(btrfssum.CSum{}):]) if err != nil { return nodeRef, fmt.Errorf("btrfs.ReadNode: node@%v: %w", addr, err) } @@ -375,13 +377,13 @@ func ReadNode[Addr ~int64](fs util.File[Addr], sb Superblock, addr Addr, laddrCB return nodeRef, nil } -func (fs *FS) ReadNode(addr LogicalAddr) (*util.Ref[LogicalAddr, Node], error) { +func (fs *FS) ReadNode(addr btrfsvol.LogicalAddr) (*util.Ref[btrfsvol.LogicalAddr, Node], error) { sb, err := fs.Superblock() if err != nil { return nil, fmt.Errorf("btrfs.FS.ReadNode: %w", err) } - return ReadNode[LogicalAddr](fs, sb.Data, addr, func(claimAddr LogicalAddr) error { + return ReadNode[btrfsvol.LogicalAddr](fs, sb.Data, addr, func(claimAddr btrfsvol.LogicalAddr) error { if claimAddr != addr { return fmt.Errorf("read from laddr=%v but claims to be at laddr=%v", addr, claimAddr) @@ -390,7 +392,7 @@ func (fs *FS) ReadNode(addr LogicalAddr) (*util.Ref[LogicalAddr, Node], error) { }) } -func (fs *FS) readNodeAtLevel(addr LogicalAddr, expLevel uint8) (*util.Ref[LogicalAddr, Node], error) { +func (fs *FS) readNodeAtLevel(addr btrfsvol.LogicalAddr, expLevel uint8) (*util.Ref[btrfsvol.LogicalAddr, Node], error) { node, err := fs.ReadNode(addr) if err != nil { return node, err diff --git a/pkg/btrfs/types_superblock.go b/pkg/btrfs/types_superblock.go index 3ed1055..413e5da 100644 --- a/pkg/btrfs/types_superblock.go +++ b/pkg/btrfs/types_superblock.go @@ -6,20 +6,22 @@ import ( "lukeshu.com/btrfs-tools/pkg/binstruct" "lukeshu.com/btrfs-tools/pkg/btrfs/btrfsitem" + "lukeshu.com/btrfs-tools/pkg/btrfs/btrfssum" + "lukeshu.com/btrfs-tools/pkg/btrfs/btrfsvol" "lukeshu.com/btrfs-tools/pkg/util" ) type Superblock struct { - Checksum CSum `bin:"off=0x0, siz=0x20"` // Checksum of everything past this field (from 20 to 1000) - FSUUID UUID `bin:"off=0x20, siz=0x10"` // FS UUID - Self PhysicalAddr `bin:"off=0x30, siz=0x8"` // physical address of this block (different for mirrors) - Flags uint64 `bin:"off=0x38, siz=0x8"` // flags - Magic [8]byte `bin:"off=0x40, siz=0x8"` // magic ('_BHRfS_M') - Generation Generation `bin:"off=0x48, siz=0x8"` + Checksum btrfssum.CSum `bin:"off=0x0, siz=0x20"` // Checksum of everything past this field (from 0x20 to 0x1000) + FSUUID UUID `bin:"off=0x20, siz=0x10"` // FS UUID + Self btrfsvol.PhysicalAddr `bin:"off=0x30, siz=0x8"` // physical address of this block (different for mirrors) + Flags uint64 `bin:"off=0x38, siz=0x8"` // flags + Magic [8]byte `bin:"off=0x40, siz=0x8"` // magic ('_BHRfS_M') + Generation Generation `bin:"off=0x48, siz=0x8"` - RootTree LogicalAddr `bin:"off=0x50, siz=0x8"` // logical address of the root tree root - ChunkTree LogicalAddr `bin:"off=0x58, siz=0x8"` // logical address of the chunk tree root - LogTree LogicalAddr `bin:"off=0x60, siz=0x8"` // logical address of the log tree root + RootTree btrfsvol.LogicalAddr `bin:"off=0x50, siz=0x8"` // logical address of the root tree root + ChunkTree btrfsvol.LogicalAddr `bin:"off=0x58, siz=0x8"` // logical address of the chunk tree root + LogTree btrfsvol.LogicalAddr `bin:"off=0x60, siz=0x8"` // logical address of the log tree root LogRootTransID uint64 `bin:"off=0x68, siz=0x8"` // log_root_transid TotalBytes uint64 `bin:"off=0x70, siz=0x8"` // total_bytes @@ -33,11 +35,11 @@ type Superblock struct { StripeSize uint32 `bin:"off=0x9c, siz=0x4"` SysChunkArraySize uint32 `bin:"off=0xa0, siz=0x4"` - ChunkRootGeneration Generation `bin:"off=0xa4, siz=0x8"` - CompatFlags uint64 `bin:"off=0xac, siz=0x8"` // compat_flags - CompatROFlags uint64 `bin:"off=0xb4, siz=0x8"` // compat_ro_flags - only implementations that support the flags can write to the filesystem - IncompatFlags IncompatFlags `bin:"off=0xbc, siz=0x8"` // incompat_flags - only implementations that support the flags can use the filesystem - ChecksumType CSumType `bin:"off=0xc4, siz=0x2"` + ChunkRootGeneration Generation `bin:"off=0xa4, siz=0x8"` + CompatFlags uint64 `bin:"off=0xac, siz=0x8"` // compat_flags + CompatROFlags uint64 `bin:"off=0xb4, siz=0x8"` // compat_ro_flags - only implementations that support the flags can write to the filesystem + IncompatFlags IncompatFlags `bin:"off=0xbc, siz=0x8"` // incompat_flags - only implementations that support the flags can use the filesystem + ChecksumType btrfssum.CSumType `bin:"off=0xc4, siz=0x2"` RootLevel uint8 `bin:"off=0xc6, siz=0x1"` // root_level ChunkLevel uint8 `bin:"off=0xc7, siz=0x1"` // chunk_root_level @@ -55,9 +57,9 @@ type Superblock struct { NumGlobalRoots uint64 `bin:"off=0x24b, siz=0x8"` // FeatureIncompatExtentTreeV2 - BlockGroupRoot LogicalAddr `bin:"off=0x253, siz=0x8"` - BlockGroupRootGeneration Generation `bin:"off=0x25b, siz=0x8"` - BlockGroupRootLevel uint8 `bin:"off=0x263, siz=0x1"` + BlockGroupRoot btrfsvol.LogicalAddr `bin:"off=0x253, siz=0x8"` + BlockGroupRootGeneration Generation `bin:"off=0x25b, siz=0x8"` + BlockGroupRootLevel uint8 `bin:"off=0x263, siz=0x1"` Reserved [199]byte `bin:"off=0x264, siz=0xc7"` // future expansion @@ -69,12 +71,12 @@ type Superblock struct { binstruct.End `bin:"off=0x1000"` } -func (sb Superblock) CalculateChecksum() (CSum, error) { +func (sb Superblock) CalculateChecksum() (btrfssum.CSum, error) { data, err := binstruct.Marshal(sb) if err != nil { - return CSum{}, err + return btrfssum.CSum{}, err } - return sb.ChecksumType.Sum(data[binstruct.StaticSize(CSum{}):]) + return sb.ChecksumType.Sum(data[binstruct.StaticSize(btrfssum.CSum{}):]) } func (sb Superblock) ValidateChecksum() error { @@ -91,10 +93,10 @@ func (sb Superblock) ValidateChecksum() error { } func (a Superblock) Equal(b Superblock) bool { - a.Checksum = CSum{} + a.Checksum = btrfssum.CSum{} a.Self = 0 - b.Checksum = CSum{} + b.Checksum = btrfssum.CSum{} b.Self = 0 return reflect.DeepEqual(a, b) |