From 3825cf60fd652f22acc438d50028701d27a7402d Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Wed, 1 Jun 2022 01:27:19 -0600 Subject: wow --- pkg/btrfs/btrfsitem/item_chunk.go | 62 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 pkg/btrfs/btrfsitem/item_chunk.go (limited to 'pkg/btrfs/btrfsitem/item_chunk.go') diff --git a/pkg/btrfs/btrfsitem/item_chunk.go b/pkg/btrfs/btrfsitem/item_chunk.go new file mode 100644 index 0000000..41706c3 --- /dev/null +++ b/pkg/btrfs/btrfsitem/item_chunk.go @@ -0,0 +1,62 @@ +package btrfsitem + +import ( + "lukeshu.com/btrfs-tools/pkg/binstruct" + "lukeshu.com/btrfs-tools/pkg/btrfs/btrfstyp" +) + +type Chunk struct { // CHUNK_ITEM=228 + // Maps logical address to physical. + Size uint64 `bin:"off=0x0, siz=0x8"` // size of chunk (bytes) + Owner btrfstyp.ObjID `bin:"off=0x8, siz=0x8"` // root referencing this chunk (2) + StripeLen uint64 `bin:"off=0x10, siz=0x8"` // stripe length + Type uint64 `bin:"off=0x18, siz=0x8"` // type (same as flags for block group?) + IOOptimalAlign uint32 `bin:"off=0x20, siz=0x4"` // optimal io alignment + IOOptimalWidth uint32 `bin:"off=0x24, siz=0x4"` // optimal io width + IoMinSize uint32 `bin:"off=0x28, siz=0x4"` // minimal io size (sector size) + NumStripes uint16 `bin:"off=0x2c, siz=0x2"` // number of stripes + SubStripes uint16 `bin:"off=0x2e, siz=0x2"` // sub stripes + binstruct.End `bin:"off=0x30"` + Stripes []ChunkStripe `bin:"-"` +} + +type ChunkStripe struct { + // Stripes follow (for each number of stripes): + DeviceID btrfstyp.ObjID `bin:"off=0, siz=8"` // device ID + Offset uint64 `bin:"off=8, siz=8"` // offset + DeviceUUID btrfstyp.UUID `bin:"off=10, siz=10"` // device UUID + binstruct.End `bin:"off=20"` +} + +func (chunk *Chunk) UnmarshalBinary(dat []byte) (int, error) { + n, err := binstruct.UnmarshalWithoutInterface(dat, chunk) + if err != nil { + return n, err + } + for i := 0; i < int(chunk.NumStripes); i++ { + var stripe ChunkStripe + _n, err := binstruct.Unmarshal(dat[n:], &stripe) + n += _n + if err != nil { + return n, err + } + chunk.Stripes = append(chunk.Stripes, stripe) + } + return n, nil +} + +func (chunk Chunk) MarshalBinary() ([]byte, error) { + chunk.NumStripes = uint16(len(chunk.Stripes)) + ret, err := binstruct.MarshalWithoutInterface(chunk) + if err != nil { + return ret, err + } + for _, stripe := range chunk.Stripes { + _ret, err := binstruct.Marshal(stripe) + ret = append(ret, _ret...) + if err != nil { + return ret, err + } + } + return ret, nil +} -- cgit v1.2.3-2-g168b