summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@lukeshu.com>2022-06-01 01:56:16 -0600
committerLuke Shumaker <lukeshu@lukeshu.com>2022-06-01 01:56:16 -0600
commit70fc3adf402eb956e6061fae75e46c46c1ad606d (patch)
tree5611c676dcb91405d7a327e42f664f2496107944
parent3825cf60fd652f22acc438d50028701d27a7402d (diff)
update main, kinda
-rw-r--r--cmd/btrfs-dump-tree/main.go215
-rw-r--r--pkg/btrfs/Makefile2
-rw-r--r--pkg/btrfs/btrfsitem/item_chunk.go8
-rw-r--r--pkg/btrfs/btrfsitem/item_dev.go10
-rw-r--r--pkg/btrfs/btrfsitem/item_devextent.go6
-rw-r--r--pkg/btrfs/btrfsitem/item_inode.go10
-rw-r--r--pkg/btrfs/btrfsitem/item_inoderef.go23
-rw-r--r--pkg/btrfs/btrfsitem/item_root.go22
-rw-r--r--pkg/btrfs/btrfsitem/item_uuid.go6
-rw-r--r--pkg/btrfs/btrfsitem/items.go.bak193
-rw-r--r--pkg/btrfs/fsck.go1
-rw-r--r--pkg/btrfs/internal.go20
-rw-r--r--pkg/btrfs/internal/misc.go (renamed from pkg/btrfs/btrfstyp/misc.go)9
-rw-r--r--pkg/btrfs/internal/objid.go (renamed from pkg/btrfs/btrfstyp/objid.go)19
-rw-r--r--pkg/btrfs/internal/uuid.go (renamed from pkg/btrfs/btrfstyp/uuid.go)2
-rw-r--r--pkg/btrfs/io1_device.go1
-rw-r--r--pkg/btrfs/io2_fs.go1
-rw-r--r--pkg/btrfs/types_btree.go1
-rw-r--r--pkg/btrfs/types_superblock.go1
19 files changed, 197 insertions, 353 deletions
diff --git a/cmd/btrfs-dump-tree/main.go b/cmd/btrfs-dump-tree/main.go
index ca9d527..d5aa94e 100644
--- a/cmd/btrfs-dump-tree/main.go
+++ b/cmd/btrfs-dump-tree/main.go
@@ -7,6 +7,8 @@ import (
"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"
)
func main() {
@@ -72,64 +74,68 @@ func Main(imgfilename string) (err error) {
// printTree mimics btrfs-progs kernel-shared/print-tree.c:btrfs_print_tree() and kernel-shared/print-tree.c:btrfs_print_leaf()
func printTree(fs *btrfs.FS, root btrfs.LogicalAddr) {
- node, err := fs.ReadNode(root)
+ nodeRef, err := fs.ReadNode(root)
if err != nil {
fmt.Printf("error: %v\n", err)
return
}
+ node := nodeRef.Data
printHeaderInfo(node)
- switch node := node.(type) {
- case *btrfs.InternalNode:
- for _, item := range node.Body {
+ if node.Head.Level > 0 { // internal
+ for _, item := range node.BodyInternal {
fmt.Printf("\t%s block %d gen %d\n",
- fmtKey(item.Data.Key),
- item.Data.BlockPtr,
- item.Data.Generation)
+ fmtKey(item.Key),
+ item.BlockPtr,
+ item.Generation)
}
- for _, item := range node.Body {
- printTree(fs, item.Data.BlockPtr)
+ for _, item := range node.BodyInternal {
+ printTree(fs, item.BlockPtr)
}
- case *btrfs.LeafNode:
- for i, item := range node.Body {
+ } else { // leaf
+ for i, item := range node.BodyLeaf {
fmt.Printf("\titem %d %s itemoff %d itemsize %d\n",
i,
- fmtKey(item.Data.Key),
- item.Data.DataOffset,
- item.Data.DataSize)
- switch item.Data.Key.ItemType {
- case btrfs.BTRFS_UNTYPED_KEY:
- // TODO
- case btrfs.BTRFS_INODE_ITEM_KEY:
- // TODO(!)
- case btrfs.BTRFS_INODE_REF_KEY:
- dat := item.Data.Data.Data
+ fmtKey(item.Head.Key),
+ item.Head.DataOffset,
+ item.Head.DataSize)
+ switch item.Head.Key.ItemType {
+ //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 btrfs.InodeRefItem
- if err := binstruct.Unmarshal(dat, &ref); err != nil {
+ var ref btrfsitem.InodeRef
+ n, err := binstruct.Unmarshal(dat, &ref)
+ if err != nil {
fmt.Printf("error: %v\n", err)
return
}
- dat = dat[0xA:]
- ref.Name = dat[:ref.NameLen]
- dat = dat[ref.NameLen:]
-
fmt.Printf("\t\tindex %d namelen %d name: %s\n",
ref.Index, ref.NameLen, ref.Name)
+ dat = dat[n:]
}
- case btrfs.BTRFS_INODE_EXTREF_KEY:
- // TODO
- case btrfs.BTRFS_DIR_ITEM_KEY, btrfs.BTRFS_DIR_INDEX_KEY, btrfs.BTRFS_XATTR_ITEM_KEY:
- // TODO
- case btrfs.BTRFS_DIR_LOG_INDEX_KEY, btrfs.BTRFS_DIR_LOG_ITEM_KEY:
- // TODO
- case btrfs.BTRFS_ORPHAN_ITEM_KEY:
+ //case btrfsitem.INODE_EXTREF_KEY:
+ // // TODO
+ //case btrfsitem.DIR_ITEM_KEY, btrfsitem.DIR_INDEX_KEY, btrfsitem.XATTR_ITEM_KEY:
+ // // 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 btrfs.BTRFS_ROOT_ITEM_KEY:
- var obj btrfs.RootItem
- if err := binstruct.Unmarshal(item.Data.Data.Data, &obj); err != nil {
+ case btrfsitem.ROOT_ITEM_KEY:
+ var obj btrfsitem.Root
+ n, err := binstruct.Unmarshal(item.Body, &obj)
+ if err != nil {
fmt.Printf("error: %v\n", err)
return
}
+ if n != len(item.Body) {
+ fmt.Printf("error: left over data: got %d bytes but only consumed %d\n", len(item.Body), n)
+ return
+ }
+
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)
fmt.Printf("\t\tlast_snapshot %d flags %s refs %d\n",
@@ -149,58 +155,58 @@ func printTree(fs *btrfs.FS, root btrfs.LogicalAddr) {
fmt.Printf("\t\tstime %s\n", fmtTime(obj.STime))
fmt.Printf("\t\trtime %s\n", fmtTime(obj.RTime))
}
- case btrfs.BTRFS_ROOT_REF_KEY:
- // TODO
- case btrfs.BTRFS_ROOT_BACKREF_KEY:
- // TODO
- case btrfs.BTRFS_EXTENT_ITEM_KEY:
- // TODO
- case btrfs.BTRFS_METADATA_ITEM_KEY:
- // TODO
- case btrfs.BTRFS_TREE_BLOCK_REF_KEY:
+ //case btrfsitem.ROOT_REF_KEY:
+ // // TODO
+ //case btrfsitem.ROOT_BACKREF_KEY:
+ // // TODO
+ //case btrfsitem.EXTENT_ITEM_KEY:
+ // // TODO
+ //case btrfsitem.METADATA_ITEM_KEY:
+ // // TODO
+ case btrfsitem.TREE_BLOCK_REF_KEY:
fmt.Printf("\t\ttree block backref\n")
- case btrfs.BTRFS_SHARED_BLOCK_REF_KEY:
+ case btrfsitem.SHARED_BLOCK_REF_KEY:
fmt.Printf("\t\tshared block backref\n")
- case btrfs.BTRFS_EXTENT_DATA_REF_KEY:
- // TODO
- case btrfs.BTRFS_SHARED_DATA_REF_KEY:
- // TODO
- case btrfs.BTRFS_EXTENT_REF_V0_KEY:
+ //case btrfsitem.EXTENT_DATA_REF_KEY:
+ // // TODO
+ //case btrfsitem.SHARED_DATA_REF_KEY:
+ // // TODO
+ case btrfsitem.EXTENT_REF_V0_KEY:
fmt.Printf("\t\textent ref v0 (deprecated)\n")
- case btrfs.BTRFS_CSUM_ITEM_KEY:
+ case btrfsitem.CSUM_ITEM_KEY:
fmt.Printf("\t\tcsum item\n")
- case btrfs.BTRFS_EXTENT_CSUM_KEY:
- // TODO
- case btrfs.BTRFS_EXTENT_DATA_KEY:
- // TODO
- case btrfs.BTRFS_BLOCK_GROUP_ITEM_KEY:
- // TODO
- case btrfs.BTRFS_FREE_SPACE_INFO_KEY:
- // TODO
- case btrfs.BTRFS_FREE_SPACE_EXTENT_KEY:
+ //case btrfsitem.EXTENT_CSUM_KEY:
+ // // TODO
+ //case btrfsitem.EXTENT_DATA_KEY:
+ // // TODO
+ //case btrfsitem.BLOCK_GROUP_ITEM_KEY:
+ // // TODO
+ //case btrfsitem.FREE_SPACE_INFO_KEY:
+ // // TODO
+ case btrfsitem.FREE_SPACE_EXTENT_KEY:
fmt.Printf("\t\tfree space extent\n")
- case btrfs.BTRFS_FREE_SPACE_BITMAP_KEY:
+ case btrfsitem.FREE_SPACE_BITMAP_KEY:
fmt.Printf("\t\tfree space bitmap\n")
- case btrfs.BTRFS_CHUNK_ITEM_KEY:
- // TODO(!)
- case btrfs.BTRFS_DEV_ITEM_KEY:
- // TODO
- case btrfs.BTRFS_DEV_EXTENT_KEY:
- // TODO
- case btrfs.BTRFS_QGROUP_STATUS_KEY:
- // TODO
- case btrfs.BTRFS_QGROUP_RELATION_KEY, btrfs.BTRFS_QGROUP_INFO_KEY:
- // TODO
- case btrfs.BTRFS_QGROUP_LIMIT_KEY:
- // TODO
- case btrfs.BTRFS_UUID_KEY_SUBVOL, btrfs.BTRFS_UUID_KEY_RECEIVED_SUBVOL:
- // TODO
- case btrfs.BTRFS_STRING_ITEM_KEY:
- // TODO
- case btrfs.BTRFS_PERSISTENT_ITEM_KEY:
- // TODO
- case btrfs.BTRFS_TEMPORARY_ITEM_KEY:
- // TODO
+ //case btrfsitem.CHUNK_ITEM_KEY:
+ // // TODO(!)
+ //case btrfsitem.DEV_ITEM_KEY:
+ // // TODO
+ //case btrfsitem.DEV_EXTENT_KEY:
+ // // TODO
+ //case btrfsitem.QGROUP_STATUS_KEY:
+ // // TODO
+ //case btrfsitem.QGROUP_RELATION_KEY, btrfsitem.QGROUP_INFO_KEY:
+ // // TODO
+ //case btrfsitem.QGROUP_LIMIT_KEY:
+ // // TODO
+ //case btrfsitem.UUID_KEY_SUBVOL, btrfsitem.UUID_KEY_RECEIVED_SUBVOL:
+ // // TODO
+ //case btrfsitem.STRING_ITEM_KEY:
+ // // TODO
+ //case btrfsitem.PERSISTENT_ITEM_KEY:
+ // // TODO
+ //case btrfsitem.TEMPORARY_ITEM_KEY:
+ // // TODO
}
}
}
@@ -209,36 +215,35 @@ func printTree(fs *btrfs.FS, root btrfs.LogicalAddr) {
// printHeaderInfo mimics btrfs-progs kernel-shared/print-tree.c:print_header_info()
func printHeaderInfo(node btrfs.Node) {
var typename string
- switch node := node.(type) {
- case *btrfs.InternalNode:
+ if node.Head.Level > 0 { // internal node
typename = "node"
fmt.Printf("node %d level %d items %d free space %d",
- node.Header.Addr,
- node.Header.Data.Level,
- node.Header.Data.NumItems,
- node.Header.Data.MaxItems-node.Header.Data.NumItems)
- case *btrfs.LeafNode:
+ node.Head.Addr,
+ node.Head.Level,
+ node.Head.NumItems,
+ node.MaxItems()-node.Head.NumItems)
+ } else { // leaf node
typename = "leaf"
fmt.Printf("leaf %d items %d free space %d",
- node.Header.Addr,
- node.Header.Data.NumItems,
- node.FreeSpace())
+ node.Head.Addr,
+ node.Head.NumItems,
+ node.LeafFreeSpace())
}
fmt.Printf(" generation %d owner %v\n",
- node.GetNodeHeader().Data.Generation,
- node.GetNodeHeader().Data.Owner)
+ node.Head.Generation,
+ node.Head.Owner)
fmt.Printf("%s %d flags %s backref revision %d\n",
typename,
- node.GetNodeHeader().Addr,
- node.GetNodeHeader().Data.Flags,
- node.GetNodeHeader().Data.BackrefRev)
+ node.Head.Addr,
+ node.Head.Flags,
+ node.Head.BackrefRev)
- fmt.Printf("checksum stored %x\n", node.GetNodeHeader().Data.Checksum)
+ fmt.Printf("checksum stored %x\n", node.Head.Checksum)
fmt.Printf("checksum calced %v\n", "TODO")
- fmt.Printf("fs uuid %s\n", node.GetNodeHeader().Data.MetadataUUID)
- fmt.Printf("chunk uuid %s\n", node.GetNodeHeader().Data.ChunkTreeUUID)
+ fmt.Printf("fs uuid %s\n", node.Head.MetadataUUID)
+ fmt.Printf("chunk uuid %s\n", node.Head.ChunkTreeUUID)
}
// mimics print-tree.c:btrfs_print_key()
@@ -246,14 +251,14 @@ func fmtKey(key btrfs.Key) string {
var out strings.Builder
fmt.Fprintf(&out, "key (%s %v", key.ObjectID.Format(key.ItemType), key.ItemType)
switch key.ItemType {
- case btrfs.BTRFS_QGROUP_RELATION_KEY, btrfs.BTRFS_QGROUP_INFO_KEY, btrfs.BTRFS_QGROUP_LIMIT_KEY:
+ case btrfsitem.QGROUP_RELATION_KEY, btrfsitem.QGROUP_INFO_KEY, btrfsitem.QGROUP_LIMIT_KEY:
panic("not implemented")
- case btrfs.BTRFS_UUID_KEY_SUBVOL, btrfs.BTRFS_UUID_KEY_RECEIVED_SUBVOL:
+ case btrfsitem.UUID_KEY_SUBVOL, btrfsitem.UUID_KEY_RECEIVED_SUBVOL:
fmt.Fprintf(&out, " 0x%016x)", key.Offset)
- case btrfs.BTRFS_ROOT_ITEM_KEY:
+ case btrfsitem.ROOT_ITEM_KEY:
fmt.Fprintf(&out, " %v)", btrfs.ObjID(key.Offset))
default:
- if key.Offset == btrfs.MaxUint64pp-1 {
+ if key.Offset == util.MaxUint64pp-1 {
fmt.Fprintf(&out, " -1)")
} else {
fmt.Fprintf(&out, " %d)", key.Offset)
diff --git a/pkg/btrfs/Makefile b/pkg/btrfs/Makefile
index cf3a911..781eb7c 100644
--- a/pkg/btrfs/Makefile
+++ b/pkg/btrfs/Makefile
@@ -2,8 +2,6 @@
.SECONDARY:
.DELETE_ON_ERROR:
-internal:
- mkdir $@
btrfsitem/items.txt: btrfsitem $(wildcard btrfsitem/item_*.go) $(MAKEFILE_LIST)
sed -En 's,^type (\S+) .* // (.*=.*),\1 \2,p' $(filter btrfsitem/item_%.go,$^) | while read -r typ keys; do for key in $$keys; do echo "$$key" "$$typ"; done; done >$@
files += btrfsitem/items.txt
diff --git a/pkg/btrfs/btrfsitem/item_chunk.go b/pkg/btrfs/btrfsitem/item_chunk.go
index 41706c3..17f069c 100644
--- a/pkg/btrfs/btrfsitem/item_chunk.go
+++ b/pkg/btrfs/btrfsitem/item_chunk.go
@@ -2,13 +2,13 @@ package btrfsitem
import (
"lukeshu.com/btrfs-tools/pkg/binstruct"
- "lukeshu.com/btrfs-tools/pkg/btrfs/btrfstyp"
+ "lukeshu.com/btrfs-tools/pkg/btrfs/internal"
)
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)
+ Owner internal.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
@@ -22,9 +22,9 @@ type Chunk struct { // CHUNK_ITEM=228
type ChunkStripe struct {
// Stripes follow (for each number of stripes):
- DeviceID btrfstyp.ObjID `bin:"off=0, siz=8"` // device ID
+ DeviceID internal.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
+ DeviceUUID internal.UUID `bin:"off=10, siz=10"` // device UUID
binstruct.End `bin:"off=20"`
}
diff --git a/pkg/btrfs/btrfsitem/item_dev.go b/pkg/btrfs/btrfsitem/item_dev.go
index f474156..fea34d5 100644
--- a/pkg/btrfs/btrfsitem/item_dev.go
+++ b/pkg/btrfs/btrfsitem/item_dev.go
@@ -2,11 +2,11 @@ package btrfsitem
import (
"lukeshu.com/btrfs-tools/pkg/binstruct"
- "lukeshu.com/btrfs-tools/pkg/btrfs/btrfstyp"
+ "lukeshu.com/btrfs-tools/pkg/btrfs/internal"
)
type Dev struct { // DEV_ITEM=216
- DeviceID btrfstyp.ObjID `bin:"off=0x0, siz=0x8"` // device ID
+ DeviceID internal.ObjID `bin:"off=0x0, siz=0x8"` // device ID
NumBytes uint64 `bin:"off=0x8, siz=0x8"` // number of bytes
NumBytesUsed uint64 `bin:"off=0x10, siz=0x8"` // number of bytes used
@@ -16,14 +16,14 @@ type Dev struct { // DEV_ITEM=216
IOMinSize uint32 `bin:"off=0x20, siz=0x4"` // minimal I/O size (sector size)
Type uint64 `bin:"off=0x24, siz=0x8"` // type
- Generation btrfstyp.Generation `bin:"off=0x2c, siz=0x8"` // generation
+ Generation internal.Generation `bin:"off=0x2c, siz=0x8"` // generation
StartOffset uint64 `bin:"off=0x34, siz=0x8"` // start offset
DevGroup uint32 `bin:"off=0x3c, siz=0x4"` // dev group
SeekSpeed uint8 `bin:"off=0x40, siz=0x1"` // seek speed
Bandwidth uint8 `bin:"off=0x41, siz=0x1"` // bandwidth
- DevUUID btrfstyp.UUID `bin:"off=0x42, siz=0x10"` // device UUID
- FSUUID btrfstyp.UUID `bin:"off=0x52, siz=0x10"` // FS UUID
+ DevUUID internal.UUID `bin:"off=0x42, siz=0x10"` // device UUID
+ FSUUID internal.UUID `bin:"off=0x52, siz=0x10"` // FS UUID
binstruct.End `bin:"off=0x62"`
}
diff --git a/pkg/btrfs/btrfsitem/item_devextent.go b/pkg/btrfs/btrfsitem/item_devextent.go
index 4bdd1c3..fbfa6fb 100644
--- a/pkg/btrfs/btrfsitem/item_devextent.go
+++ b/pkg/btrfs/btrfsitem/item_devextent.go
@@ -2,14 +2,14 @@ package btrfsitem
import (
"lukeshu.com/btrfs-tools/pkg/binstruct"
- "lukeshu.com/btrfs-tools/pkg/btrfs/btrfstyp"
+ "lukeshu.com/btrfs-tools/pkg/btrfs/internal"
)
type DevExtent struct { // DEV_EXTENT=204
ChunkTree int64 `bin:"off=0, siz=8"`
- ChunkObjectID btrfstyp.ObjID `bin:"off=8, siz=8"`
+ ChunkObjectID internal.ObjID `bin:"off=8, siz=8"`
ChunkOffset int64 `bin:"off=16, siz=8"`
Length int64 `bin:"off=24, siz=8"`
- ChunkTreeUUID btrfstyp.UUID `bin:"off=32, siz=16"`
+ ChunkTreeUUID internal.UUID `bin:"off=32, siz=16"`
binstruct.End `bin:"off=48"`
}
diff --git a/pkg/btrfs/btrfsitem/item_inode.go b/pkg/btrfs/btrfsitem/item_inode.go
index 0c7600e..4d38380 100644
--- a/pkg/btrfs/btrfsitem/item_inode.go
+++ b/pkg/btrfs/btrfsitem/item_inode.go
@@ -2,7 +2,7 @@ package btrfsitem
import (
"lukeshu.com/btrfs-tools/pkg/binstruct"
- "lukeshu.com/btrfs-tools/pkg/btrfs/btrfstyp"
+ "lukeshu.com/btrfs-tools/pkg/btrfs/internal"
)
type Inode struct { // INODE_ITEM=1
@@ -19,9 +19,9 @@ type Inode struct { // INODE_ITEM=1
Flags uint64 `bin:"off=0x40, siz=0x8"`
Sequence int64 `bin:"off=0x48, siz=0x8"`
Reserved [4]int64 `bin:"off=0x50, siz=0x20"`
- ATime btrfstyp.Time `bin:"off=0x70, siz=0xc"`
- CTime btrfstyp.Time `bin:"off=0x7c, siz=0xc"`
- MTime btrfstyp.Time `bin:"off=0x88, siz=0xc"`
- OTime btrfstyp.Time `bin:"off=0x94, siz=0xc"`
+ ATime internal.Time `bin:"off=0x70, siz=0xc"`
+ CTime internal.Time `bin:"off=0x7c, siz=0xc"`
+ MTime internal.Time `bin:"off=0x88, siz=0xc"`
+ OTime internal.Time `bin:"off=0x94, siz=0xc"`
binstruct.End `bin:"off=0xa0"`
}
diff --git a/pkg/btrfs/btrfsitem/item_inoderef.go b/pkg/btrfs/btrfsitem/item_inoderef.go
index 5a271ae..05426b2 100644
--- a/pkg/btrfs/btrfsitem/item_inoderef.go
+++ b/pkg/btrfs/btrfsitem/item_inoderef.go
@@ -6,7 +6,28 @@ import (
type InodeRef struct { // INODE_REF=12
Index int64 `bin:"off=0x0, siz=0x8"`
- NameLen int16 `bin:"off=0x8, siz=0x2"`
+ NameLen uint16 `bin:"off=0x8, siz=0x2"`
binstruct.End `bin:"off=0xa"`
Name []byte `bin:"-"`
}
+
+func (o *InodeRef) UnmarshalBinary(dat []byte) (int, error) {
+ n, err := binstruct.UnmarshalWithoutInterface(dat, o)
+ if err != nil {
+ return n, err
+ }
+ dat = dat[n:]
+ o.Name = dat[:o.NameLen]
+ n += int(o.NameLen)
+ return n, nil
+}
+
+func (o InodeRef) MarshalBinary() ([]byte, error) {
+ o.NameLen = uint16(len(o.Name))
+ dat, err := binstruct.MarshalWithoutInterface(o)
+ if err != nil {
+ return dat, err
+ }
+ dat = append(dat, o.Name...)
+ return dat, nil
+}
diff --git a/pkg/btrfs/btrfsitem/item_root.go b/pkg/btrfs/btrfsitem/item_root.go
index c87a49b..a7867e8 100644
--- a/pkg/btrfs/btrfsitem/item_root.go
+++ b/pkg/btrfs/btrfsitem/item_root.go
@@ -2,7 +2,7 @@ package btrfsitem
import (
"lukeshu.com/btrfs-tools/pkg/binstruct"
- "lukeshu.com/btrfs-tools/pkg/btrfs/btrfstyp"
+ "lukeshu.com/btrfs-tools/pkg/btrfs/internal"
"lukeshu.com/btrfs-tools/pkg/util"
)
@@ -10,28 +10,28 @@ type Root struct { // ROOT_ITEM=132
Inode Inode `bin:"off=0x0, siz=0xa0"`
Generation int64 `bin:"off=0xa0, siz=0x8"`
RootDirID int64 `bin:"off=0xa8, siz=0x8"`
- ByteNr btrfstyp.LogicalAddr `bin:"off=0xb0, siz=0x8"`
+ ByteNr internal.LogicalAddr `bin:"off=0xb0, siz=0x8"`
ByteLimit int64 `bin:"off=0xb8, siz=0x8"`
BytesUsed int64 `bin:"off=0xc0, siz=0x8"`
LastSnapshot int64 `bin:"off=0xc8, siz=0x8"`
Flags RootFlags `bin:"off=0xd0, siz=0x8"`
Refs int32 `bin:"off=0xd8, siz=0x4"`
- DropProgress btrfstyp.Key `bin:"off=0xdc, siz=0x11"`
+ DropProgress internal.Key `bin:"off=0xdc, siz=0x11"`
DropLevel uint8 `bin:"off=0xed, siz=0x1"`
Level uint8 `bin:"off=0xee, siz=0x1"`
GenerationV2 int64 `bin:"off=0xef, siz=0x8"`
- UUID btrfstyp.UUID `bin:"off=0xF7, siz=0x10"`
- ParentUUID btrfstyp.UUID `bin:"off=0x107, siz=0x10"`
- ReceivedUUID btrfstyp.UUID `bin:"off=0x117, siz=0x10"`
+ UUID internal.UUID `bin:"off=0xF7, siz=0x10"`
+ ParentUUID internal.UUID `bin:"off=0x107, siz=0x10"`
+ ReceivedUUID internal.UUID `bin:"off=0x117, siz=0x10"`
CTransID int64 `bin:"off=0x127, siz=0x8"`
OTransID int64 `bin:"off=0x12f, siz=0x8"`
STransID int64 `bin:"off=0x137, siz=0x8"`
RTransID int64 `bin:"off=0x13f, siz=0x8"`
- CTime btrfstyp.Time `bin:"off=0x147, siz=0xc"`
- OTime btrfstyp.Time `bin:"off=0x153, siz=0xc"`
- STime btrfstyp.Time `bin:"off=0x15F, siz=0xc"`
- RTime btrfstyp.Time `bin:"off=0x16b, siz=0xc"`
- GlobalTreeID btrfstyp.ObjID `bin:"off=0x177, siz=0x8"`
+ CTime internal.Time `bin:"off=0x147, siz=0xc"`
+ OTime internal.Time `bin:"off=0x153, siz=0xc"`
+ STime internal.Time `bin:"off=0x15F, siz=0xc"`
+ RTime internal.Time `bin:"off=0x16b, siz=0xc"`
+ GlobalTreeID internal.ObjID `bin:"off=0x177, siz=0x8"`
Reserved [7]int64 `bin:"off=0x17f, siz=0x38"`
binstruct.End `bin:"off=0x1b7"`
}
diff --git a/pkg/btrfs/btrfsitem/item_uuid.go b/pkg/btrfs/btrfsitem/item_uuid.go
index 315dd70..894ccff 100644
--- a/pkg/btrfs/btrfsitem/item_uuid.go
+++ b/pkg/btrfs/btrfsitem/item_uuid.go
@@ -2,20 +2,20 @@ package btrfsitem
import (
"lukeshu.com/btrfs-tools/pkg/binstruct"
- "lukeshu.com/btrfs-tools/pkg/btrfs/btrfstyp"
+ "lukeshu.com/btrfs-tools/pkg/btrfs/internal"
)
// The Key for this item is a UUID, and the item is a list of
// subvolume IDs (ObjectIDs) that that UUID maps to.
type UUIDMap struct { // UUID_SUBVOL=251 UUID_RECEIVED_SUBVOL=252
- SubvolIDs []btrfstyp.ObjID
+ SubvolIDs []internal.ObjID
}
func (o *UUIDMap) UnmarshalBinary(dat []byte) (int, error) {
o.SubvolIDs = nil
var n int
for len(dat) > n {
- var subvolID btrfstyp.ObjID
+ var subvolID internal.ObjID
_n, err := binstruct.Unmarshal(dat[n:], &subvolID)
n += _n
if err != nil {
diff --git a/pkg/btrfs/btrfsitem/items.go.bak b/pkg/btrfs/btrfsitem/items.go.bak
deleted file mode 100644
index 9a91d97..0000000
--- a/pkg/btrfs/btrfsitem/items.go.bak
+++ /dev/null
@@ -1,193 +0,0 @@
-package btrfsitem
-
-import (
- "lukeshu.com/btrfs-tools/pkg/btrfs/btrfstyp"
-)
-
-type Type = btrfstyp.ItemType
-
-const (
- BTRFS_UNTYPED_KEY = btrfstyp.ItemType(0)
-
- // inode items have the data typically returned from stat and store other
- // info about object characteristics. There is one for every file and dir in
- // the FS
- BTRFS_INODE_ITEM_KEY = btrfstyp.ItemType(1)
- BTRFS_INODE_REF_KEY = btrfstyp.ItemType(12)
- BTRFS_INODE_EXTREF_KEY = btrfstyp.ItemType(13)
- BTRFS_XATTR_ITEM_KEY = btrfstyp.ItemType(24)
-
- BTRFS_VERITY_DESC_ITEM_KEY = btrfstyp.ItemType(36) // new
- BTRFS_VERITY_MERKLE_ITEM_KEY = btrfstyp.ItemType(37) // new
-
- BTRFS_ORPHAN_ITEM_KEY = btrfstyp.ItemType(48)
-
- BTRFS_DIR_LOG_ITEM_KEY = btrfstyp.ItemType(60)
- BTRFS_DIR_LOG_INDEX_KEY = btrfstyp.ItemType(72)
- // dir items are the name -> inode pointers in a directory. There is one
- // for every name in a directory.
- BTRFS_DIR_ITEM_KEY = btrfstyp.ItemType(84)
- BTRFS_DIR_INDEX_KEY = btrfstyp.ItemType(96)
-
- // extent data is for file data
- BTRFS_EXTENT_DATA_KEY = btrfstyp.ItemType(108)
-
- // csum items have the checksums for data in the extents
- BTRFS_CSUM_ITEM_KEY = btrfstyp.ItemType(120) // new
- // extent csums are stored in a separate tree and hold csums for
- // an entire extent on disk.
- BTRFS_EXTENT_CSUM_KEY = btrfstyp.ItemType(128)
-
- // root items point to tree roots. There are typically in the root
- // tree used by the super block to find all the other trees
- BTRFS_ROOT_ITEM_KEY = btrfstyp.ItemType(132)
-
- // root backrefs tie subvols and snapshots to the directory entries that
- // reference them
- BTRFS_ROOT_BACKREF_KEY = btrfstyp.ItemType(144)
-
- // root refs make a fast index for listing all of the snapshots and
- // subvolumes referenced by a given root. They point directly to the
- // directory item in the root that references the subvol
- BTRFS_ROOT_REF_KEY = btrfstyp.ItemType(156)
-
- // extent items are in the extent map tree. These record which blocks
- // are used, and how many references there are to each block
- BTRFS_EXTENT_ITEM_KEY = btrfstyp.ItemType(168)
-
- // The same as the BTRFS_EXTENT_ITEM_KEY, except it's metadata we already know
- // the length, so we save the level in key->offset instead of the length.
- BTRFS_METADATA_ITEM_KEY = btrfstyp.ItemType(169) // new
-
- BTRFS_TREE_BLOCK_REF_KEY = btrfstyp.ItemType(176)
-
- BTRFS_EXTENT_DATA_REF_KEY = btrfstyp.ItemType(178)
-
- // old style extent backrefs
- BTRFS_EXTENT_REF_V0_KEY = btrfstyp.ItemType(180)
-
- BTRFS_SHARED_BLOCK_REF_KEY = btrfstyp.ItemType(182)
-
- BTRFS_SHARED_DATA_REF_KEY = btrfstyp.ItemType(184)
-
- // block groups give us hints into the extent allocation trees. Which
- // blocks are free etc etc
- BTRFS_BLOCK_GROUP_ITEM_KEY = btrfstyp.ItemType(192)
-
- // Every block group is represented in the free space tree by a free space info
- // item, which stores some accounting information. It is keyed on
- // (block_group_start, FREE_SPACE_INFO, block_group_length).
- BTRFS_FREE_SPACE_INFO_KEY = btrfstyp.ItemType(198) // new
-
- // A free space extent tracks an extent of space that is free in a block group.
- // It is keyed on (start, FREE_SPACE_EXTENT, length).
- BTRFS_FREE_SPACE_EXTENT_KEY = btrfstyp.ItemType(199) // new
-
- // When a block group becomes very fragmented, we convert it to use bitmaps
- // instead of extents. A free space bitmap is keyed on
- // (start, FREE_SPACE_BITMAP, length); the corresponding item is a bitmap with
- // (length / sectorsize) bits.
- BTRFS_FREE_SPACE_BITMAP_KEY = btrfstyp.ItemType(200) // new
-
- BTRFS_DEV_EXTENT_KEY = btrfstyp.ItemType(204)
- BTRFS_DEV_ITEM_KEY = btrfstyp.ItemType(216)
- BTRFS_CHUNK_ITEM_KEY = btrfstyp.ItemType(228)
-
- // quota groups
- BTRFS_QGROUP_STATUS_KEY = btrfstyp.ItemType(240) // new
- BTRFS_QGROUP_INFO_KEY = btrfstyp.ItemType(242) // new
- BTRFS_QGROUP_LIMIT_KEY = btrfstyp.ItemType(244) // new
- BTRFS_QGROUP_RELATION_KEY = btrfstyp.ItemType(246) // new
-
- // The key type for tree items that are stored persistently, but do not need to
- // exist for extended period of time. The items can exist in any tree.
- //
- // [subtype, BTRFS_TEMPORARY_ITEM_KEY, data]
- //
- // Existing items:
- //
- // - balance status item
- // (BTRFS_BALANCE_OBJECTID, BTRFS_TEMPORARY_ITEM_KEY, 0)
- BTRFS_TEMPORARY_ITEM_KEY = btrfstyp.ItemType(248) // new
-
- // The key type for tree items that are stored persistently and usually exist
- // for a long period, eg. filesystem lifetime. The item kinds can be status
- // information, stats or preference values. The item can exist in any tree.
- //
- // [subtype, BTRFS_PERSISTENT_ITEM_KEY, data]
- //
- // Existing items:
- //
- // - device statistics, store IO stats in the device tree, one key for all
- // stats
- // (BTRFS_DEV_STATS_OBJECTID, BTRFS_DEV_STATS_KEY, 0)
- BTRFS_PERSISTENT_ITEM_KEY = btrfstyp.ItemType(249) // new
-
- // Persistently stores the device replace state in the device tree.
- // The key is built like this: (0, BTRFS_DEV_REPLACE_KEY, 0).
- BTRFS_DEV_REPLACE_KEY = btrfstyp.ItemType(250)
-
- // Stores items that allow to quickly map UUIDs to something else.
- // These items are part of the filesystem UUID tree.
- // The key is built like this:
- // (UUID_upper_64_bits, BTRFS_UUID_KEY*, UUID_lower_64_bits).
- BTRFS_UUID_KEY_SUBVOL = btrfstyp.ItemType(251) // for UUIDs assigned to subvols // new
- BTRFS_UUID_KEY_RECEIVED_SUBVOL = btrfstyp.ItemType(252) // for UUIDs assigned to received subvols // new
-
- // string items are for debugging. They just store a short string of
- // data in the FS
- BTRFS_STRING_ITEM_KEY = btrfstyp.ItemType(253)
-)
-
-/*
-func (t btrfstyp.ItemType) String() string {
- names := map[btrfstyp.ItemType]string{
- BTRFS_UNTYPED_KEY: "UNTYPED",
- BTRFS_INODE_ITEM_KEY: "INODE_ITEM",
- BTRFS_INODE_REF_KEY: "INODE_REF",
- BTRFS_INODE_EXTREF_KEY: "INODE_EXTREF",
- BTRFS_XATTR_ITEM_KEY: "XATTR_ITEM",
- BTRFS_VERITY_DESC_ITEM_KEY: "VERITY_DESC_ITEM",
- BTRFS_VERITY_MERKLE_ITEM_KEY: "VERITY_MERKLE_ITEM",
- BTRFS_ORPHAN_ITEM_KEY: "ORPHAN_ITEM",
- BTRFS_DIR_LOG_ITEM_KEY: "DIR_LOG_ITEM",
- BTRFS_DIR_LOG_INDEX_KEY: "DIR_LOG_INDEX",
- BTRFS_DIR_ITEM_KEY: "DIR_ITEM",
- BTRFS_DIR_INDEX_KEY: "DIR_INDEX",
- BTRFS_EXTENT_DATA_KEY: "EXTENT_DATA",
- BTRFS_CSUM_ITEM_KEY: "CSUM_ITEM",
- BTRFS_EXTENT_CSUM_KEY: "EXTENT_CSUM",
- BTRFS_ROOT_ITEM_KEY: "ROOT_ITEM",
- BTRFS_ROOT_BACKREF_KEY: "ROOT_BACKREF",
- BTRFS_ROOT_REF_KEY: "ROOT_REF",
- BTRFS_EXTENT_ITEM_KEY: "EXTENT_ITEM",
- BTRFS_METADATA_ITEM_KEY: "METADATA_ITEM",
- BTRFS_TREE_BLOCK_REF_KEY: "TREE_BLOCK_REF",
- BTRFS_EXTENT_DATA_REF_KEY: "EXTENT_DATA_REF",
- BTRFS_EXTENT_REF_V0_KEY: "EXTENT_REF_V0",
- BTRFS_SHARED_BLOCK_REF_KEY: "SHARED_BLOCK_REF",
- BTRFS_SHARED_DATA_REF_KEY: "SHARED_DATA_REF",
- BTRFS_BLOCK_GROUP_ITEM_KEY: "BLOCK_GROUP_ITEM",
- BTRFS_FREE_SPACE_INFO_KEY: "FREE_SPACE_INFO",
- BTRFS_FREE_SPACE_EXTENT_KEY: "FREE_SPACE_EXTENT",
- BTRFS_FREE_SPACE_BITMAP_KEY: "FREE_SPACE_BITMAP",
- BTRFS_DEV_EXTENT_KEY: "DEV_EXTENT",
- BTRFS_DEV_ITEM_KEY: "DEV_ITEM",
- BTRFS_CHUNK_ITEM_KEY: "CHUNK_ITEM",
- BTRFS_QGROUP_STATUS_KEY: "QGROUP_STATUS",
- BTRFS_QGROUP_INFO_KEY: "QGROUP_INFO",
- BTRFS_QGROUP_LIMIT_KEY: "QGROUP_LIMIT",
- BTRFS_QGROUP_RELATION_KEY: "QGROUP_RELATION",
- BTRFS_TEMPORARY_ITEM_KEY: "TEMPORARY_ITEM",
- BTRFS_PERSISTENT_ITEM_KEY: "PERSISTENT_ITEM",
- BTRFS_DEV_REPLACE_KEY: "DEV_REPLACE",
- BTRFS_UUID_KEY_SUBVOL: "UUID_KEY_SUBVOL",
- BTRFS_UUID_KEY_RECEIVED_SUBVOL: "UUID_KEY_RECEIVED_SUBVOL",
- BTRFS_STRING_ITEM_KEY: "STRING_ITEM",
- }
- if name, ok := names[t]; ok {
- return name
- }
- return fmt.Sprintf("%d", t)
-}
-*/
diff --git a/pkg/btrfs/fsck.go b/pkg/btrfs/fsck.go
index 3220a12..33ccd44 100644
--- a/pkg/btrfs/fsck.go
+++ b/pkg/btrfs/fsck.go
@@ -4,7 +4,6 @@ import (
"fmt"
"lukeshu.com/btrfs-tools/pkg/binstruct"
- . "lukeshu.com/btrfs-tools/pkg/btrfs/btrfstyp"
)
// ScanForNodes mimics btrfs-progs
diff --git a/pkg/btrfs/internal.go b/pkg/btrfs/internal.go
new file mode 100644
index 0000000..5c0fc8b
--- /dev/null
+++ b/pkg/btrfs/internal.go
@@ -0,0 +1,20 @@
+package btrfs
+
+import (
+ "lukeshu.com/btrfs-tools/pkg/btrfs/internal"
+)
+
+type (
+ // (u)int64 types
+
+ Generation = internal.Generation
+ ObjID = internal.ObjID
+ LogicalAddr = internal.LogicalAddr
+ PhysicalAddr = internal.PhysicalAddr
+
+ // complex types
+
+ Key = internal.Key
+ Time = internal.Time
+ UUID = internal.UUID
+)
diff --git a/pkg/btrfs/btrfstyp/misc.go b/pkg/btrfs/internal/misc.go
index b0847f8..e7d9dd6 100644
--- a/pkg/btrfs/btrfstyp/misc.go
+++ b/pkg/btrfs/internal/misc.go
@@ -1,10 +1,9 @@
-package btrfstyp
+package internal
import (
"time"
"lukeshu.com/btrfs-tools/pkg/binstruct"
- "lukeshu.com/btrfs-tools/pkg/btrfs/internal"
)
type (
@@ -14,9 +13,9 @@ type (
)
type Key struct {
- ObjectID ObjID `bin:"off=0, siz=8"` // Each tree has its own set of Object IDs.
- ItemType internal.ItemType `bin:"off=8, siz=1"`
- Offset uint64 `bin:"off=9, siz=8"` // The meaning depends on the item type.
+ ObjectID ObjID `bin:"off=0, siz=8"` // Each tree has its own set of Object IDs.
+ ItemType ItemType `bin:"off=8, siz=1"`
+ Offset uint64 `bin:"off=9, siz=8"` // The meaning depends on the item type.
binstruct.End `bin:"off=11"`
}
diff --git a/pkg/btrfs/btrfstyp/objid.go b/pkg/btrfs/internal/objid.go
index dce8c18..c3b25f3 100644
--- a/pkg/btrfs/btrfstyp/objid.go
+++ b/pkg/btrfs/internal/objid.go
@@ -1,9 +1,8 @@
-package btrfstyp
+package internal
import (
"fmt"
- "lukeshu.com/btrfs-tools/pkg/btrfs/internal"
"lukeshu.com/btrfs-tools/pkg/util"
)
@@ -52,9 +51,9 @@ const (
BTRFS_EMPTY_SUBVOL_DIR_OBJECTID = ObjID(2)
)
-func (id ObjID) Format(typ internal.ItemType) string {
+func (id ObjID) Format(typ ItemType) string {
switch typ {
- case internal.PERSISTENT_ITEM_KEY:
+ case PERSISTENT_ITEM_KEY:
names := map[ObjID]string{
BTRFS_DEV_STATS_OBJECTID: "DEV_STATS",
}
@@ -62,15 +61,15 @@ func (id ObjID) Format(typ internal.ItemType) string {
return name
}
return fmt.Sprintf("%d", int64(id))
- case internal.DEV_EXTENT_KEY:
+ case DEV_EXTENT_KEY:
return fmt.Sprintf("%d", int64(id))
- case internal.QGROUP_RELATION_KEY:
+ case QGROUP_RELATION_KEY:
return fmt.Sprintf("%d/%d",
uint64(id)>>48,
uint64(id)&((1<<48)-1))
- case internal.UUID_SUBVOL_KEY, internal.UUID_RECEIVED_SUBVOL_KEY:
+ case UUID_SUBVOL_KEY, UUID_RECEIVED_SUBVOL_KEY:
return fmt.Sprintf("0x%016x", uint64(id))
- case internal.DEV_ITEM_KEY:
+ case DEV_ITEM_KEY:
names := map[ObjID]string{
BTRFS_BALANCE_OBJECTID: "BALANCE",
BTRFS_ORPHAN_OBJECTID: "ORPHAN",
@@ -89,7 +88,7 @@ func (id ObjID) Format(typ internal.ItemType) string {
return name
}
return fmt.Sprintf("%d", int64(id))
- case internal.CHUNK_ITEM_KEY:
+ case CHUNK_ITEM_KEY:
names := map[ObjID]string{
BTRFS_BALANCE_OBJECTID: "BALANCE",
BTRFS_ORPHAN_OBJECTID: "ORPHAN",
@@ -141,5 +140,5 @@ func (id ObjID) Format(typ internal.ItemType) string {
}
func (id ObjID) String() string {
- return id.Format(internal.UNTYPED_KEY)
+ return id.Format(UNTYPED_KEY)
}
diff --git a/pkg/btrfs/btrfstyp/uuid.go b/pkg/btrfs/internal/uuid.go
index 8b0c92e..ff274d9 100644
--- a/pkg/btrfs/btrfstyp/uuid.go
+++ b/pkg/btrfs/internal/uuid.go
@@ -1,4 +1,4 @@
-package btrfstyp
+package internal
import (
"bytes"
diff --git a/pkg/btrfs/io1_device.go b/pkg/btrfs/io1_device.go
index ed418a0..efd8cb9 100644
--- a/pkg/btrfs/io1_device.go
+++ b/pkg/btrfs/io1_device.go
@@ -4,7 +4,6 @@ import (
"fmt"
"os"
- . "lukeshu.com/btrfs-tools/pkg/btrfs/btrfstyp"
"lukeshu.com/btrfs-tools/pkg/util"
)
diff --git a/pkg/btrfs/io2_fs.go b/pkg/btrfs/io2_fs.go
index 9b1e717..a74d4a3 100644
--- a/pkg/btrfs/io2_fs.go
+++ b/pkg/btrfs/io2_fs.go
@@ -7,7 +7,6 @@ import (
"lukeshu.com/btrfs-tools/pkg/binstruct"
"lukeshu.com/btrfs-tools/pkg/btrfs/btrfsitem"
- . "lukeshu.com/btrfs-tools/pkg/btrfs/btrfstyp"
"lukeshu.com/btrfs-tools/pkg/util"
)
diff --git a/pkg/btrfs/types_btree.go b/pkg/btrfs/types_btree.go
index 2807cee..1eb104d 100644
--- a/pkg/btrfs/types_btree.go
+++ b/pkg/btrfs/types_btree.go
@@ -5,7 +5,6 @@ import (
"fmt"
"lukeshu.com/btrfs-tools/pkg/binstruct"
- . "lukeshu.com/btrfs-tools/pkg/btrfs/btrfstyp"
"lukeshu.com/btrfs-tools/pkg/util"
)
diff --git a/pkg/btrfs/types_superblock.go b/pkg/btrfs/types_superblock.go
index 1b69c03..47dd3b0 100644
--- a/pkg/btrfs/types_superblock.go
+++ b/pkg/btrfs/types_superblock.go
@@ -6,7 +6,6 @@ import (
"lukeshu.com/btrfs-tools/pkg/binstruct"
"lukeshu.com/btrfs-tools/pkg/btrfs/btrfsitem"
- . "lukeshu.com/btrfs-tools/pkg/btrfs/btrfstyp"
"lukeshu.com/btrfs-tools/pkg/util"
)