summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@lukeshu.com>2022-06-01 10:09:47 -0600
committerLuke Shumaker <lukeshu@lukeshu.com>2022-06-01 10:09:47 -0600
commit8dde45b09728fb753b072c73ff624dde832c073b (patch)
tree779eac71af7fb88f323f877c0395d99c711058c3
parent437bf733021a6aa3b90042a12a35b887b8ed45a2 (diff)
update main
-rw-r--r--cmd/btrfs-dump-tree/main.go72
-rw-r--r--pkg/btrfs/btrfsitem/item_inoderef.go32
-rw-r--r--pkg/btrfs/btrfsitem/items.txt2
-rw-r--r--pkg/btrfs/btrfsitem/items_gen.go22
4 files changed, 68 insertions, 60 deletions
diff --git a/cmd/btrfs-dump-tree/main.go b/cmd/btrfs-dump-tree/main.go
index 46fd741..a1c7a03 100644
--- a/cmd/btrfs-dump-tree/main.go
+++ b/cmd/btrfs-dump-tree/main.go
@@ -5,7 +5,6 @@ import (
"os"
"strings"
- "lukeshu.com/btrfs-tools/pkg/binstruct"
"lukeshu.com/btrfs-tools/pkg/btrfs"
"lukeshu.com/btrfs-tools/pkg/btrfs/btrfsitem"
"lukeshu.com/btrfs-tools/pkg/util"
@@ -76,19 +75,11 @@ func Main(imgfilename string) (err error) {
return err
}
}
- if err := fs.WalkTree(superblock.Data.RootTree, func(key btrfs.Key, dat []byte) error {
+ if err := fs.WalkTree(superblock.Data.RootTree, func(key btrfs.Key, body btrfsitem.Item) error {
if key.ItemType != btrfsitem.ROOT_ITEM_KEY {
return nil
}
- var obj btrfsitem.Root
- n, err := binstruct.Unmarshal(dat, &obj)
- if err != nil {
- return err
- }
- if n != len(dat) {
- return fmt.Errorf("left over data: got %d bytes but only consumed %d", len(dat), n)
- }
- return printTree(fs, obj.ByteNr)
+ return printTree(fs, body.(btrfsitem.Root).ByteNr)
}); err != nil {
return err
}
@@ -123,22 +114,15 @@ func printTree(fs *btrfs.FS, root btrfs.LogicalAddr) error {
fmtKey(item.Head.Key),
item.Head.DataOffset,
item.Head.DataSize)
- switch item.Head.Key.ItemType {
+ switch body := item.Body.(type) {
//case btrfsitem.UNTYPED_KEY:
// // TODO
//case btrfsitem.INODE_ITEM_KEY:
// // TODO(!)
- case btrfsitem.INODE_REF_KEY:
- dat := item.Body
- for len(dat) > 0 {
- var ref btrfsitem.InodeRef
- n, err := binstruct.Unmarshal(dat, &ref)
- if err != nil {
- return err
- }
+ case btrfsitem.InodeRefList:
+ for _, ref := range body {
fmt.Printf("\t\tindex %d namelen %d name: %s\n",
ref.Index, ref.NameLen, ref.Name)
- dat = dat[n:]
}
//case btrfsitem.INODE_EXTREF_KEY:
// // TODO
@@ -146,36 +130,32 @@ func printTree(fs *btrfs.FS, root btrfs.LogicalAddr) error {
// // TODO
//case btrfsitem.DIR_LOG_INDEX_KEY, btrfsitem.DIR_LOG_ITEM_KEY:
// // TODO
- case btrfsitem.ORPHAN_ITEM_KEY:
- fmt.Printf("\t\torphan item\n")
- case btrfsitem.ROOT_ITEM_KEY:
- var obj btrfsitem.Root
- n, err := binstruct.Unmarshal(item.Body, &obj)
- if err != nil {
- return err
+ case btrfsitem.Empty:
+ switch item.Head.Key.ItemType {
+ case btrfsitem.ORPHAN_ITEM_KEY:
+ fmt.Printf("\t\torphan item\n")
+ default:
+ return fmt.Errorf("unhandled empty item type: %v", item.Head.Key.ItemType)
}
- if n != len(item.Body) {
- return fmt.Errorf("left over data: got %d bytes but only consumed %d", len(item.Body), n)
- }
-
+ case btrfsitem.Root:
fmt.Printf("\t\tgeneration %d root_dirid %d bytenr %d byte_limit %d bytes_used %d\n",
- obj.Generation, obj.RootDirID, obj.ByteNr, obj.ByteLimit, obj.BytesUsed)
+ body.Generation, body.RootDirID, body.ByteNr, body.ByteLimit, body.BytesUsed)
fmt.Printf("\t\tlast_snapshot %d flags %s refs %d\n",
- obj.LastSnapshot, obj.Flags, obj.Refs)
+ body.LastSnapshot, body.Flags, body.Refs)
fmt.Printf("\t\tdrop_progress %s drop_level %d\n",
- fmtKey(obj.DropProgress), obj.DropLevel)
+ fmtKey(body.DropProgress), body.DropLevel)
fmt.Printf("\t\tlevel %d generation_v2 %d\n",
- obj.Level, obj.GenerationV2)
- if obj.Generation == obj.GenerationV2 {
- fmt.Printf("\t\tuuid %s\n", obj.UUID)
- fmt.Printf("\t\tparent_uuid %s\n", obj.ParentUUID)
- fmt.Printf("\t\treceived_uuid %s\n", obj.ReceivedUUID)
+ body.Level, body.GenerationV2)
+ if body.Generation == body.GenerationV2 {
+ fmt.Printf("\t\tuuid %s\n", body.UUID)
+ fmt.Printf("\t\tparent_uuid %s\n", body.ParentUUID)
+ fmt.Printf("\t\treceived_uuid %s\n", body.ReceivedUUID)
fmt.Printf("\t\tctransid %d otransid %d stransid %d rtransid %d\n",
- obj.CTransID, obj.OTransID, obj.STransID, obj.RTransID)
- fmt.Printf("\t\tctime %s\n", fmtTime(obj.CTime))
- fmt.Printf("\t\totime %s\n", fmtTime(obj.OTime))
- fmt.Printf("\t\tstime %s\n", fmtTime(obj.STime))
- fmt.Printf("\t\trtime %s\n", fmtTime(obj.RTime))
+ body.CTransID, body.OTransID, body.STransID, body.RTransID)
+ fmt.Printf("\t\tctime %s\n", fmtTime(body.CTime))
+ fmt.Printf("\t\totime %s\n", fmtTime(body.OTime))
+ fmt.Printf("\t\tstime %s\n", fmtTime(body.STime))
+ fmt.Printf("\t\trtime %s\n", fmtTime(body.RTime))
}
//case btrfsitem.ROOT_REF_KEY:
// // TODO
@@ -221,7 +201,7 @@ func printTree(fs *btrfs.FS, root btrfs.LogicalAddr) error {
// // TODO
//case btrfsitem.QGROUP_LIMIT_KEY:
// // TODO
- case btrfsitem.UUID_SUBVOL_KEY, btrfsitem.UUID_RECEIVED_SUBVOL_KEY:
+ case btrfsitem.UUIDMap:
// TODO
//case btrfsitem.STRING_ITEM_KEY:
// // TODO
diff --git a/pkg/btrfs/btrfsitem/item_inoderef.go b/pkg/btrfs/btrfsitem/item_inoderef.go
index 05426b2..e59c4b3 100644
--- a/pkg/btrfs/btrfsitem/item_inoderef.go
+++ b/pkg/btrfs/btrfsitem/item_inoderef.go
@@ -4,8 +4,36 @@ import (
"lukeshu.com/btrfs-tools/pkg/binstruct"
)
-type InodeRef struct { // INODE_REF=12
- Index int64 `bin:"off=0x0, siz=0x8"`
+type InodeRefList []InodeRef // INODE_REF=12
+
+func (o *InodeRefList) UnmarshalBinary(dat []byte) (int, error) {
+ n := 0
+ for n < len(dat) {
+ var ref InodeRef
+ _n, err := binstruct.Unmarshal(dat, &ref)
+ n += _n
+ if err != nil {
+ return n, err
+ }
+ *o = append(*o, ref)
+ }
+ return n, nil
+}
+
+func (o InodeRefList) MarshalBinary() ([]byte, error) {
+ var ret []byte
+ for _, ref := range o {
+ bs, err := binstruct.Marshal(ref)
+ ret = append(ret, bs...)
+ if err != nil {
+ return ret, err
+ }
+ }
+ return ret, nil
+}
+
+type InodeRef struct {
+ Index int64 `bin:"off=0x0, siz=0x8"`
NameLen uint16 `bin:"off=0x8, siz=0x2"`
binstruct.End `bin:"off=0xa"`
Name []byte `bin:"-"`
diff --git a/pkg/btrfs/btrfsitem/items.txt b/pkg/btrfs/btrfsitem/items.txt
index 02c1d24..f38af3f 100644
--- a/pkg/btrfs/btrfsitem/items.txt
+++ b/pkg/btrfs/btrfsitem/items.txt
@@ -4,7 +4,7 @@ DEV_EXTENT=204 DevExtent
UNTYPED=0, Empty
QGROUP_RELATION=246 Empty
INODE_ITEM=1 Inode
-INODE_REF=12 InodeRef
+INODE_REF=12 InodeRefList
ORPHAN_ITEM=48 Orphan
PERSISTENT_ITEM=249 DevStats
ROOT_ITEM=132 Root
diff --git a/pkg/btrfs/btrfsitem/items_gen.go b/pkg/btrfs/btrfsitem/items_gen.go
index 40a0b53..63a5ac1 100644
--- a/pkg/btrfs/btrfsitem/items_gen.go
+++ b/pkg/btrfs/btrfsitem/items_gen.go
@@ -28,7 +28,7 @@ var keytype2gotype = map[Type]reflect.Type{
UNTYPED_KEY: reflect.TypeOf(Empty{}),
QGROUP_RELATION_KEY: reflect.TypeOf(Empty{}),
INODE_ITEM_KEY: reflect.TypeOf(Inode{}),
- INODE_REF_KEY: reflect.TypeOf(InodeRef{}),
+ INODE_REF_KEY: reflect.TypeOf(InodeRefList{}),
ORPHAN_ITEM_KEY: reflect.TypeOf(Orphan{}),
PERSISTENT_ITEM_KEY: reflect.TypeOf(DevStats{}),
ROOT_ITEM_KEY: reflect.TypeOf(Root{}),
@@ -36,13 +36,13 @@ var keytype2gotype = map[Type]reflect.Type{
UUID_RECEIVED_SUBVOL_KEY: reflect.TypeOf(UUIDMap{}),
}
-func (Chunk) isItem() {}
-func (Dev) isItem() {}
-func (DevExtent) isItem() {}
-func (DevStats) isItem() {}
-func (Empty) isItem() {}
-func (Inode) isItem() {}
-func (InodeRef) isItem() {}
-func (Orphan) isItem() {}
-func (Root) isItem() {}
-func (UUIDMap) isItem() {}
+func (Chunk) isItem() {}
+func (Dev) isItem() {}
+func (DevExtent) isItem() {}
+func (DevStats) isItem() {}
+func (Empty) isItem() {}
+func (Inode) isItem() {}
+func (InodeRefList) isItem() {}
+func (Orphan) isItem() {}
+func (Root) isItem() {}
+func (UUIDMap) isItem() {}