From bb73a2fb7678698353bb995754e8702caa2f6e0a Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Thu, 14 Jul 2022 04:45:48 -0600 Subject: wip ls-files --- lib/btrfs/btrfsitem/item_fileextent.go | 24 ++++++++++++----------- lib/btrfs/btrfsitem/item_inode.go | 2 +- lib/btrfs/btrfsitem/item_inoderef.go | 36 ++++++++++++++++++++++++++++++++-- lib/btrfs/btrfsitem/items_gen.go | 4 ++-- 4 files changed, 50 insertions(+), 16 deletions(-) (limited to 'lib/btrfs/btrfsitem') diff --git a/lib/btrfs/btrfsitem/item_fileextent.go b/lib/btrfs/btrfsitem/item_fileextent.go index a69c67a..b7e394e 100644 --- a/lib/btrfs/btrfsitem/item_fileextent.go +++ b/lib/btrfs/btrfsitem/item_fileextent.go @@ -28,20 +28,22 @@ type FileExtent struct { // EXTENT_DATA=108 binstruct.End `bin:"off=0x15"` // only one of these, depending on .Type - BodyInline []byte `bin:"-"` // .Type == FILE_EXTENT_INLINE - BodyExtent struct { // .Type == FILE_EXTENT_REG or FILE_EXTENT_PREALLOC - // Position and size of extent within the device - DiskByteNr btrfsvol.LogicalAddr `bin:"off=0x0, siz=0x8"` - DiskNumBytes btrfsvol.AddrDelta `bin:"off=0x8, siz=0x8"` + BodyInline []byte `bin:"-"` // .Type == FILE_EXTENT_INLINE + BodyExtent FileExtentExtent `bin:"-"` // .Type == FILE_EXTENT_REG or FILE_EXTENT_PREALLOC +} + +type FileExtentExtent struct { + // Position and size of extent within the device + DiskByteNr btrfsvol.LogicalAddr `bin:"off=0x0, siz=0x8"` + DiskNumBytes btrfsvol.AddrDelta `bin:"off=0x8, siz=0x8"` - // Position of data within the extent - Offset btrfsvol.AddrDelta `bin:"off=0x10, siz=0x8"` + // Position of data within the extent + Offset btrfsvol.AddrDelta `bin:"off=0x10, siz=0x8"` - // Decompressed/unencrypted size - NumBytes int64 `bin:"off=0x18, siz=0x8"` + // Decompressed/unencrypted size + NumBytes int64 `bin:"off=0x18, siz=0x8"` - binstruct.End `bin:"off=0x20"` - } `bin:"-"` + binstruct.End `bin:"off=0x20"` } func (o *FileExtent) UnmarshalBinary(dat []byte) (int, error) { diff --git a/lib/btrfs/btrfsitem/item_inode.go b/lib/btrfs/btrfsitem/item_inode.go index 27204f6..49b2031 100644 --- a/lib/btrfs/btrfsitem/item_inode.go +++ b/lib/btrfs/btrfsitem/item_inode.go @@ -14,7 +14,7 @@ type Inode struct { // INODE_ITEM=1 Generation internal.Generation `bin:"off=0x00, siz=0x08"` TransID int64 `bin:"off=0x08, siz=0x08"` Size int64 `bin:"off=0x10, siz=0x08"` // stat - NumBytes int64 `bin:"off=0x18, siz=0x08"` + NumBytes int64 `bin:"off=0x18, siz=0x08"` // allocated bytes, may be larger than size (or smaller if there are holes?) BlockGroup int64 `bin:"off=0x20, siz=0x08"` NLink int32 `bin:"off=0x28, siz=0x04"` // stat UID int32 `bin:"off=0x2C, siz=0x04"` // stat diff --git a/lib/btrfs/btrfsitem/item_inoderef.go b/lib/btrfs/btrfsitem/item_inoderef.go index b1eaf1b..083f19e 100644 --- a/lib/btrfs/btrfsitem/item_inoderef.go +++ b/lib/btrfs/btrfsitem/item_inoderef.go @@ -12,8 +12,40 @@ import ( ) // key.objectid = inode number of the file -// key.offset = inode number of the parent file -type InodeRef struct { // INODE_REF=12 +// key.offset = inode number of the parent directory +// +// Might have multiple entries if the same file has multiple hardlinks +// in the same directory. +type InodeRefs []InodeRef // INODE_REF=12 + +func (o *InodeRefs) UnmarshalBinary(dat []byte) (int, error) { + *o = nil + n := 0 + for n < len(dat) { + var ref InodeRef + _n, err := binstruct.Unmarshal(dat[n:], &ref) + n += _n + if err != nil { + return n, err + } + *o = append(*o, ref) + } + return n, nil +} + +func (o InodeRefs) MarshalBinary() ([]byte, error) { + var dat []byte + for _, ref := range o { + _dat, err := binstruct.Marshal(ref) + dat = append(dat, _dat...) + if err != nil { + return dat, err + } + } + return dat, nil +} + +type InodeRef struct { Index int64 `bin:"off=0x0, siz=0x8"` NameLen uint16 `bin:"off=0x8, siz=0x2"` // [ignored-when-writing] binstruct.End `bin:"off=0xa"` diff --git a/lib/btrfs/btrfsitem/items_gen.go b/lib/btrfs/btrfsitem/items_gen.go index 8573967..d21cd3e 100644 --- a/lib/btrfs/btrfsitem/items_gen.go +++ b/lib/btrfs/btrfsitem/items_gen.go @@ -57,7 +57,7 @@ var keytype2gotype = map[Type]reflect.Type{ FREE_SPACE_EXTENT_KEY: reflect.TypeOf(Empty{}), FREE_SPACE_INFO_KEY: reflect.TypeOf(FreeSpaceInfo{}), INODE_ITEM_KEY: reflect.TypeOf(Inode{}), - INODE_REF_KEY: reflect.TypeOf(InodeRef{}), + INODE_REF_KEY: reflect.TypeOf(InodeRefs{}), METADATA_ITEM_KEY: reflect.TypeOf(Metadata{}), ORPHAN_ITEM_KEY: reflect.TypeOf(Empty{}), PERSISTENT_ITEM_KEY: reflect.TypeOf(DevStats{}), @@ -91,7 +91,7 @@ func (FreeSpaceBitmap) isItem() {} func (FreeSpaceHeader) isItem() {} func (FreeSpaceInfo) isItem() {} func (Inode) isItem() {} -func (InodeRef) isItem() {} +func (InodeRefs) isItem() {} func (Metadata) isItem() {} func (Root) isItem() {} func (RootRef) isItem() {} -- cgit v1.2.3-54-g00ecf