diff options
author | Luke Shumaker <lukeshu@lukeshu.com> | 2022-05-10 04:46:06 -0600 |
---|---|---|
committer | Luke Shumaker <lukeshu@lukeshu.com> | 2022-05-10 04:46:06 -0600 |
commit | 2744e0700ca6fe956f569d47010fd4e693fedcfa (patch) | |
tree | 17cc6eb920ece3700a10a86ed465d4a0947d32c4 | |
parent | a16049ef805c0c08b90885a5b7dfea7f74e51c5f (diff) |
more
-rw-r--r-- | cmd/btrfs-dbg/main.go | 8 | ||||
-rw-r--r-- | cmd/btrfs-dbg/types.go | 48 | ||||
-rw-r--r-- | go.mod | 10 | ||||
-rw-r--r-- | pkg/binstruct/l1.go | 6 | ||||
-rw-r--r-- | pkg/binstruct/l2.go | 7 | ||||
-rw-r--r-- | pkg/binstruct/l3.go | 14 |
6 files changed, 76 insertions, 17 deletions
diff --git a/cmd/btrfs-dbg/main.go b/cmd/btrfs-dbg/main.go index 8758cd0..d6c9c68 100644 --- a/cmd/btrfs-dbg/main.go +++ b/cmd/btrfs-dbg/main.go @@ -4,6 +4,8 @@ import ( "fmt" "os" + "github.com/davecgh/go-spew/spew" + "lukeshu.com/btrfs-tools/pkg/binstruct" ) @@ -36,7 +38,11 @@ func Main(imgfilename string) (err error) { if err != nil { return err } - fmt.Printf("%#v\n", superblocks[0]) + + spew := spew.NewDefaultConfig() + spew.DisablePointerAddresses = true + + spew.Dump(superblocks[0].data) return nil } diff --git a/cmd/btrfs-dbg/types.go b/cmd/btrfs-dbg/types.go index 33f78ba..699f1a2 100644 --- a/cmd/btrfs-dbg/types.go +++ b/cmd/btrfs-dbg/types.go @@ -1,15 +1,30 @@ package main import ( + "encoding/hex" + "strings" + "lukeshu.com/btrfs-tools/pkg/binstruct" ) type ( PhysicalAddr int64 LogicalAddr int64 + ObjID int64 UUID [16]byte ) +func (uuid UUID) String() string { + str := hex.EncodeToString(uuid[:]) + return strings.Join([]string{ + str[:8], + str[8:12], + str[12:16], + str[16:20], + str[20:32], + }, "-") +} + type Superblock struct { Checksum [0x20]byte `bin:"off=0, siz=20, desc=Checksum of everything past this field (from 20 to 1000)"` FSUUID UUID `bin:"off=20, siz=10, desc=FS UUID"` @@ -48,10 +63,13 @@ type Superblock struct { Label [0x100]byte `bin:"off=12b, siz=100, desc=label (may not contain '/' or '\\')"` CacheGeneration uint64 `bin:"off=22b, siz=8, desc=cache_generation"` UUIDTreeGeneration uint64 `bin:"off=233, siz=8, desc=uuid_tree_generation"` - Reserved [0xf0]byte `bin:"off=23b, siz=f0, desc=reserved /* future expansion */"` - SysChunkArray [0x800]byte `bin:"off=32b, siz=800, desc=sys_chunk_array:(n bytes valid) Contains (KEY . CHUNK_ITEM) pairs for all SYSTEM chunks. This is needed to bootstrap the mapping from logical addresses to physical. "` - SuperRoots [0x2a0]byte `bin:"off=b2b, siz=2a0, desc=Contain super_roots (4 btrfs_root_backup)"` - Unused [0x235]byte `bin:"off=dcb, siz=235, desc=current unused"` + + Reserved [0xf0]byte `bin:"off=23b, siz=f0, desc=reserved /* future expansion */"` + + TODOSysChunkArray [0x800]byte `bin:"off=32b, siz=800, desc=sys_chunk_array:(n bytes valid) Contains (KEY . CHUNK_ITEM) pairs for all SYSTEM chunks. This is needed to bootstrap the mapping from logical addresses to physical. "` + TODOSuperRoots [0x2a0]byte `bin:"off=b2b, siz=2a0, desc=Contain super_roots (4 btrfs_root_backup)"` + + Unused [0x235]byte `bin:"off=dcb, siz=235, desc=current unused"` binstruct.End `bin:"off=1000"` } @@ -78,3 +96,25 @@ type DevItem struct { binstruct.End `bin:"off=62"` } + +type ChunkItem struct { + // Maps logical address to physical. + Size uint64 `bin:"off=0, siz=8, desc=size of chunk (bytes)"` + Root ObjID `bin:"off=8, siz=8, desc=root referencing this chunk (2)"` + StripeLen uint64 `bin:"off=10, siz=8, desc=stripe length"` + Type uint64 `bin:"off=18, siz=8, desc=type (same as flags for block group?)"` + IOOptimalAlign uint32 `bin:"off=20, siz=4, desc=optimal io alignment"` + IOOptimalWidth uint32 `bin:"off=24, siz=4, desc=optimal io width"` + IoMinSize uint32 `bin:"off=28, siz=4, desc=minimal io size (sector size)"` + NumStripes uint16 `bin:"off=2c, siz=2, desc=number of stripes"` + SubStripes uint16 `bin:"off=2e, siz=2, desc=sub stripes"` + binstruct.End `bin:"off=30"` +} + +type ChunkItemStripe struct { + // Stripes follow (for each number of stripes): + DeviceID ObjID `bin:"off=0, siz=8, desc=device id"` + Offset uint64 `bin:"off=8, siz=8, desc=offset"` + DeviceUUID UUID `bin:"off=10, siz=10, desc=device UUID"` + binstruct.End `bin:"off=20"` +} @@ -2,4 +2,12 @@ module lukeshu.com/btrfs-tools go 1.18 -require github.com/stretchr/testify v1.7.1 +require ( + github.com/davecgh/go-spew v1.1.0 + github.com/stretchr/testify v1.7.1 +) + +require ( + github.com/pmezard/go-difflib v1.0.0 // indirect + gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect +) diff --git a/pkg/binstruct/l1.go b/pkg/binstruct/l1.go index c535d2e..e76e7d0 100644 --- a/pkg/binstruct/l1.go +++ b/pkg/binstruct/l1.go @@ -136,10 +136,10 @@ func genHandler(typ reflect.Type) (handler, error) { } return primitive{ unmarshal: func(dat []byte) interface{} { - val := reflect.Zero(typ) + val := reflect.New(typ).Elem() for i := 0; i < typ.Len(); i++ { - fmt.Printf("%v[%d]: %v\n", typ, i, val.Index(i)) - val.Index(i).Set(reflect.ValueOf(inner.Unmarshal(dat[i*int(inner.Size()):]))) + fieldVal := inner.Unmarshal(dat[i*int(inner.Size()):]) + val.Index(i).Set(reflect.ValueOf(fieldVal).Convert(typ.Elem())) } return val.Interface() }, diff --git a/pkg/binstruct/l2.go b/pkg/binstruct/l2.go index 005d686..32aa313 100644 --- a/pkg/binstruct/l2.go +++ b/pkg/binstruct/l2.go @@ -16,18 +16,20 @@ type structHandler struct { } type structField struct { + typ reflect.Type tag handler name string } func (sh structHandler) Unmarshal(dat []byte) interface{} { - val := reflect.Zero(sh.typ) + val := reflect.New(sh.typ).Elem() for i, field := range sh.fields { if field.skip { continue } - val.Field(i).Set(reflect.ValueOf(field.Unmarshal(dat[field.off:]))) + fieldVal := field.Unmarshal(dat[field.off:]) + val.Field(i).Set(reflect.ValueOf(fieldVal).Convert(field.typ)) } return val.Interface() } @@ -96,6 +98,7 @@ func genStructHandler(structInfo reflect.Type) (handler, error) { curOffset += fieldTag.siz ret.fields = append(ret.fields, structField{ + typ: fieldInfo.Type, tag: fieldTag, handler: fieldHandler, name: fieldInfo.Name, diff --git a/pkg/binstruct/l3.go b/pkg/binstruct/l3.go index f9fb8b1..1ccaaf0 100644 --- a/pkg/binstruct/l3.go +++ b/pkg/binstruct/l3.go @@ -21,12 +21,14 @@ func getHandler(typ reflect.Type) (handler, error) { return h, nil } -func Unmarshal(dat []byte, dst interface{}) error { - _dst := reflect.ValueOf(dst) - if _dst.Kind() != reflect.Ptr { - return fmt.Errorf("not a pointer: %v", _dst.Type()) +func Unmarshal(dat []byte, dstPtr interface{}) error { + _dstPtr := reflect.ValueOf(dstPtr) + if _dstPtr.Kind() != reflect.Ptr { + return fmt.Errorf("not a pointer: %v", _dstPtr.Type()) } - handler, err := getHandler(_dst.Type().Elem()) + + dst := _dstPtr.Elem() + handler, err := getHandler(dst.Type()) if err != nil { return err } @@ -35,7 +37,7 @@ func Unmarshal(dat []byte, dst interface{}) error { handler.Size(), len(dat)) } val := handler.Unmarshal(dat[:handler.Size()]) - _dst.Elem().Set(reflect.ValueOf(val)) + dst.Set(reflect.ValueOf(val).Convert(dst.Type())) return nil } |