summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/btrfs-dump-tree/main.go70
-rw-r--r--pkg/btrfs/Makefile2
-rw-r--r--pkg/btrfs/btrfsitem/item_dir.go38
-rw-r--r--pkg/btrfs/btrfsitem/item_extent.go10
-rw-r--r--pkg/btrfs/btrfsitem/item_inode.go24
-rw-r--r--pkg/btrfs/btrfsitem/item_persistent.go2
-rw-r--r--pkg/btrfs/btrfsitem/item_root.go2
-rw-r--r--pkg/btrfs/internal_objid.go1
8 files changed, 105 insertions, 44 deletions
diff --git a/cmd/btrfs-dump-tree/main.go b/cmd/btrfs-dump-tree/main.go
index b87778b..6a8a7e6 100644
--- a/cmd/btrfs-dump-tree/main.go
+++ b/cmd/btrfs-dump-tree/main.go
@@ -80,6 +80,30 @@ func Main(imgfilename string) (err error) {
if key.ItemType != btrfsitem.ROOT_ITEM_KEY {
return nil
}
+ treeName, ok := map[btrfs.ObjID]string{
+ btrfs.ROOT_TREE_OBJECTID: "root",
+ btrfs.EXTENT_TREE_OBJECTID: "extent",
+ btrfs.CHUNK_TREE_OBJECTID: "chunk",
+ btrfs.DEV_TREE_OBJECTID: "device",
+ btrfs.FS_TREE_OBJECTID: "fs",
+ btrfs.ROOT_TREE_DIR_OBJECTID: "directory",
+ btrfs.CSUM_TREE_OBJECTID: "checksum",
+ btrfs.ORPHAN_OBJECTID: "orphan",
+ btrfs.TREE_LOG_OBJECTID: "log",
+ btrfs.TREE_LOG_FIXUP_OBJECTID: "log fixup",
+ btrfs.TREE_RELOC_OBJECTID: "reloc",
+ btrfs.DATA_RELOC_TREE_OBJECTID: "data reloc",
+ btrfs.EXTENT_CSUM_OBJECTID: "extent checksum",
+ btrfs.QUOTA_TREE_OBJECTID: "quota",
+ btrfs.UUID_TREE_OBJECTID: "uuid",
+ btrfs.FREE_SPACE_TREE_OBJECTID: "free space",
+ btrfs.MULTIPLE_OBJECTIDS: "multiple",
+ btrfs.BLOCK_GROUP_TREE_OBJECTID: "block group",
+ }[key.ObjectID]
+ if !ok {
+ treeName = "file"
+ }
+ fmt.Printf("%s tree %s \n", treeName, fmtKey(key))
return printTree(fs, body.(btrfsitem.Root).ByteNr)
},
}); err != nil {
@@ -174,10 +198,19 @@ func printTree(fs *btrfs.FS, root btrfs.LogicalAddr) error {
// // TODO
//case btrfsitem.ROOT_BACKREF_KEY:
// // TODO
- //case btrfsitem.EXTENT_ITEM_KEY:
- // // TODO
- //case btrfsitem.METADATA_ITEM_KEY:
- // // TODO
+ case btrfsitem.Extent:
+ fmt.Printf("\t\trefs %d gen %d flags %v\n",
+ body.Head.Refs, body.Head.Generation, body.Head.Flags)
+ if body.Head.Flags.Has(btrfsitem.EXTENT_FLAG_TREE_BLOCK) {
+ fmt.Printf("\t\ttree block %s level %d\n",
+ fmtKey(body.Info.Key), body.Info.Level)
+ }
+ printExtentInlineRefs(body.Refs)
+ case btrfsitem.Metadata:
+ fmt.Printf("\t\trefs %d gen %d flags %v\n",
+ body.Head.Refs, body.Head.Generation, body.Head.Flags)
+ fmt.Printf("\t\ttree block skinny level %d\n", item.Head.Key.Offset)
+ printExtentInlineRefs(body.Refs)
//case btrfsitem.TREE_BLOCK_REF_KEY:
// fmt.Printf("\t\ttree block backref\n")
//case btrfsitem.SHARED_BLOCK_REF_KEY:
@@ -250,7 +283,7 @@ func printTree(fs *btrfs.FS, root btrfs.LogicalAddr) error {
case btrfsitem.ORPHAN_ITEM_KEY:
fmt.Printf("\t\torphan item\n")
default:
- return fmt.Errorf("unhandled empty item type: %v", item.Head.Key.ItemType)
+ fmt.Printf("\t\t(error) unhandled empty item type: %v\n", item.Head.Key.ItemType)
}
case btrfsitem.Error:
fmt.Printf("\t\t(error) error item: %v\n", body.Err)
@@ -300,6 +333,33 @@ func printHeaderInfo(node btrfs.Node) {
fmt.Printf("chunk uuid %s\n", node.Head.ChunkTreeUUID)
}
+// printExtentInlineRefs mimics part of btrfs-progs kernel-shared/print-tree.c:print_extent_item()
+func printExtentInlineRefs(refs []btrfsitem.ExtentInlineRef) {
+ for _, ref := range refs {
+ switch subitem := ref.Body.(type) {
+ case btrfsitem.Empty:
+ switch ref.Type {
+ case btrfsitem.TREE_BLOCK_REF_KEY:
+ fmt.Printf("\t\ttree block backref root %v\n",
+ btrfs.ObjID(ref.Offset))
+ case btrfsitem.SHARED_BLOCK_REF_KEY:
+ fmt.Printf("\t\tshared block backref parent %d\n",
+ ref.Offset)
+ default:
+ fmt.Printf("\t\t(error) unexpected empty sub-item type: %v\n", ref.Type)
+ }
+ case btrfsitem.ExtentDataRef:
+ fmt.Printf("\t\textent data backref root %v objectid %d offset %d count %d\n",
+ subitem.Root, subitem.ObjectID, subitem.Offset, subitem.Count)
+ case btrfsitem.SharedDataRef:
+ fmt.Printf("\t\tshared data backref parent %d count %d\n",
+ ref.Offset, subitem.Count)
+ default:
+ fmt.Printf("\t\t(error) unexpected sub-item type: %T\n", subitem)
+ }
+ }
+}
+
// mimics print-tree.c:btrfs_print_key()
func fmtKey(key btrfs.Key) string {
var out strings.Builder
diff --git a/pkg/btrfs/Makefile b/pkg/btrfs/Makefile
index 33d3793..9777cbe 100644
--- a/pkg/btrfs/Makefile
+++ b/pkg/btrfs/Makefile
@@ -57,7 +57,7 @@ internal_objid.go: internal/objid.go $(MAKEFILE_LIST)
echo '"lukeshu.com/btrfs-tools/pkg/btrfs/internal"'; \
echo ')'; \
echo 'const('; \
- sed -En 's/^\s*(\S*_OBJECTID)\s*=.*/\1 = internal.\1/p' <$<; \
+ sed -En 's/^\s*(\S*_OBJECTIDS?)\s*=.*/\1 = internal.\1/p' <$<; \
echo ')'; \
} | gofmt >$@
files += internal_objid.go
diff --git a/pkg/btrfs/btrfsitem/item_dir.go b/pkg/btrfs/btrfsitem/item_dir.go
index 2e0529e..44cfb75 100644
--- a/pkg/btrfs/btrfsitem/item_dir.go
+++ b/pkg/btrfs/btrfsitem/item_dir.go
@@ -73,29 +73,29 @@ func (o Dir) MarshalBinary() ([]byte, error) {
type FileType uint8
const (
- BTRFS_FT_UNKNOWN = FileType(0)
- BTRFS_FT_REG_FILE = FileType(1)
- BTRFS_FT_DIR = FileType(2)
- BTRFS_FT_CHRDEV = FileType(3)
- BTRFS_FT_BLKDEV = FileType(4)
- BTRFS_FT_FIFO = FileType(5)
- BTRFS_FT_SOCK = FileType(6)
- BTRFS_FT_SYMLINK = FileType(7)
- BTRFS_FT_XATTR = FileType(8)
- BTRFS_FT_MAX = FileType(9)
+ FT_UNKNOWN = FileType(0)
+ FT_REG_FILE = FileType(1)
+ FT_DIR = FileType(2)
+ FT_CHRDEV = FileType(3)
+ FT_BLKDEV = FileType(4)
+ FT_FIFO = FileType(5)
+ FT_SOCK = FileType(6)
+ FT_SYMLINK = FileType(7)
+ FT_XATTR = FileType(8)
+ FT_MAX = FileType(9)
)
func (ft FileType) String() string {
names := map[FileType]string{
- BTRFS_FT_UNKNOWN: "UNKNOWN",
- BTRFS_FT_REG_FILE: "REG_FILE",
- BTRFS_FT_DIR: "DIR",
- BTRFS_FT_CHRDEV: "CHRDEV",
- BTRFS_FT_BLKDEV: "BLKDEV",
- BTRFS_FT_FIFO: "FIFO",
- BTRFS_FT_SOCK: "SOCK",
- BTRFS_FT_SYMLINK: "SYMLINK",
- BTRFS_FT_XATTR: "XATTR",
+ FT_UNKNOWN: "UNKNOWN",
+ FT_REG_FILE: "REG_FILE",
+ FT_DIR: "DIR",
+ FT_CHRDEV: "CHRDEV",
+ FT_BLKDEV: "BLKDEV",
+ FT_FIFO: "FIFO",
+ FT_SOCK: "SOCK",
+ FT_SYMLINK: "SYMLINK",
+ FT_XATTR: "XATTR",
}
if name, ok := names[ft]; ok {
return name
diff --git a/pkg/btrfs/btrfsitem/item_extent.go b/pkg/btrfs/btrfsitem/item_extent.go
index 7d3eb05..b0b208d 100644
--- a/pkg/btrfs/btrfsitem/item_extent.go
+++ b/pkg/btrfs/btrfsitem/item_extent.go
@@ -10,7 +10,7 @@ import (
type Extent struct { // EXTENT_ITEM=168
Head ExtentHeader
- Info TreeBlockInfo // only if .Head.Flags.Has(BTRFS_EXTENT_FLAG_TREE_BLOCK)
+ Info TreeBlockInfo // only if .Head.Flags.Has(EXTENT_FLAG_TREE_BLOCK)
Refs []ExtentInlineRef
}
@@ -19,7 +19,7 @@ func (o *Extent) UnmarshalBinary(dat []byte) (int, error) {
if err != nil {
return n, err
}
- if o.Head.Flags.Has(BTRFS_EXTENT_FLAG_TREE_BLOCK) {
+ if o.Head.Flags.Has(EXTENT_FLAG_TREE_BLOCK) {
_n, err := binstruct.Unmarshal(dat[n:], &o.Info)
n += _n
if err != nil {
@@ -44,7 +44,7 @@ func (o Extent) MarshalBinary() ([]byte, error) {
if err != nil {
return dat, err
}
- if o.Head.Flags.Has(BTRFS_EXTENT_FLAG_TREE_BLOCK) {
+ if o.Head.Flags.Has(EXTENT_FLAG_TREE_BLOCK) {
bs, err := binstruct.Marshal(o.Info)
dat = append(dat, bs...)
if err != nil {
@@ -77,8 +77,8 @@ type TreeBlockInfo struct {
type ExtentFlags uint64
const (
- BTRFS_EXTENT_FLAG_DATA = ExtentFlags(1 << iota)
- BTRFS_EXTENT_FLAG_TREE_BLOCK
+ EXTENT_FLAG_DATA = ExtentFlags(1 << iota)
+ EXTENT_FLAG_TREE_BLOCK
)
var extentFlagNames = []string{
diff --git a/pkg/btrfs/btrfsitem/item_inode.go b/pkg/btrfs/btrfsitem/item_inode.go
index 175b900..e7ae666 100644
--- a/pkg/btrfs/btrfsitem/item_inode.go
+++ b/pkg/btrfs/btrfsitem/item_inode.go
@@ -30,18 +30,18 @@ type Inode struct { // INODE_ITEM=1
type InodeFlags uint64
const (
- BTRFS_INODE_NODATASUM = InodeFlags(1 << iota)
- BTRFS_INODE_NODATACOW
- BTRFS_INODE_READONLY
- BTRFS_INODE_NOCOMPRESS
- BTRFS_INODE_PREALLOC
- BTRFS_INODE_SYNC
- BTRFS_INODE_IMMUTABLE
- BTRFS_INODE_APPEND
- BTRFS_INODE_NODUMP
- BTRFS_INODE_NOATIME
- BTRFS_INODE_DIRSYNC
- BTRFS_INODE_COMPRESS
+ INODE_NODATASUM = InodeFlags(1 << iota)
+ INODE_NODATACOW
+ INODE_READONLY
+ INODE_NOCOMPRESS
+ INODE_PREALLOC
+ INODE_SYNC
+ INODE_IMMUTABLE
+ INODE_APPEND
+ INODE_NODUMP
+ INODE_NOATIME
+ INODE_DIRSYNC
+ INODE_COMPRESS
)
var inodeFlagNames = []string{
diff --git a/pkg/btrfs/btrfsitem/item_persistent.go b/pkg/btrfs/btrfsitem/item_persistent.go
index 3221800..fd69c3d 100644
--- a/pkg/btrfs/btrfsitem/item_persistent.go
+++ b/pkg/btrfs/btrfsitem/item_persistent.go
@@ -14,6 +14,6 @@ const (
)
type DevStats struct { // PERSISTENT_ITEM=249
- Values [DEV_STAT_VALUES_MAX]int64 `bin:"off=0, siz=40"`
+ Values [DEV_STAT_VALUES_MAX]int64 `bin:"off=0, siz=40"`
binstruct.End `bin:"off=40"`
}
diff --git a/pkg/btrfs/btrfsitem/item_root.go b/pkg/btrfs/btrfsitem/item_root.go
index 9dd43f8..69d2d97 100644
--- a/pkg/btrfs/btrfsitem/item_root.go
+++ b/pkg/btrfs/btrfsitem/item_root.go
@@ -39,7 +39,7 @@ type Root struct { // ROOT_ITEM=132
type RootFlags uint64
const (
- BTRFS_ROOT_SUBVOL_RDONLY = RootFlags(1 << iota)
+ ROOT_SUBVOL_RDONLY = RootFlags(1 << iota)
)
var rootFlagNames = []string{
diff --git a/pkg/btrfs/internal_objid.go b/pkg/btrfs/internal_objid.go
index c101eb6..12a58a2 100644
--- a/pkg/btrfs/internal_objid.go
+++ b/pkg/btrfs/internal_objid.go
@@ -28,6 +28,7 @@ const (
EXTENT_CSUM_OBJECTID = internal.EXTENT_CSUM_OBJECTID
FREE_SPACE_OBJECTID = internal.FREE_SPACE_OBJECTID
FREE_INO_OBJECTID = internal.FREE_INO_OBJECTID
+ MULTIPLE_OBJECTIDS = internal.MULTIPLE_OBJECTIDS
FIRST_FREE_OBJECTID = internal.FIRST_FREE_OBJECTID
LAST_FREE_OBJECTID = internal.LAST_FREE_OBJECTID
FIRST_CHUNK_TREE_OBJECTID = internal.FIRST_CHUNK_TREE_OBJECTID