summaryrefslogtreecommitdiff
path: root/lib/btrfs/btrfsitem/item_dir.go
diff options
context:
space:
mode:
Diffstat (limited to 'lib/btrfs/btrfsitem/item_dir.go')
-rw-r--r--lib/btrfs/btrfsitem/item_dir.go50
1 files changed, 17 insertions, 33 deletions
diff --git a/lib/btrfs/btrfsitem/item_dir.go b/lib/btrfs/btrfsitem/item_dir.go
index 859cd14..2fb2d41 100644
--- a/lib/btrfs/btrfsitem/item_dir.go
+++ b/lib/btrfs/btrfsitem/item_dir.go
@@ -9,47 +9,21 @@ import (
"hash/crc32"
"git.lukeshu.com/btrfs-progs-ng/lib/binstruct"
+ "git.lukeshu.com/btrfs-progs-ng/lib/binstruct/binutil"
"git.lukeshu.com/btrfs-progs-ng/lib/btrfs/internal"
)
-// key.objectid = inode of directory containing this entry
-// key.offset =
-// for DIR_ITEM and XATTR_ITEM = NameHash(name)
-// for DIR_INDEX = index id in the directory (starting at 2, because "." and "..")
-type DirEntries []DirEntry // DIR_ITEM=84 DIR_INDEX=96 XATTR_ITEM=24
+const MaxNameLen = 255
func NameHash(dat []byte) uint64 {
return uint64(^crc32.Update(1, crc32.MakeTable(crc32.Castagnoli), dat))
}
-func (o *DirEntries) UnmarshalBinary(dat []byte) (int, error) {
- *o = nil
- n := 0
- for n < len(dat) {
- var ref DirEntry
- _n, err := binstruct.Unmarshal(dat, &ref)
- n += _n
- if err != nil {
- return n, err
- }
- *o = append(*o, ref)
- }
- return n, nil
-}
-
-func (o DirEntries) 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 DirEntry struct {
+// key.objectid = inode of directory containing this entry
+// key.offset =
+// for DIR_ITEM and XATTR_ITEM = NameHash(name)
+// for DIR_INDEX = index id in the directory (starting at 2, because "." and "..")
+type DirEntry struct { // DIR_ITEM=84 DIR_INDEX=96 XATTR_ITEM=24
Location internal.Key `bin:"off=0x0, siz=0x11"`
TransID int64 `bin:"off=0x11, siz=8"`
DataLen uint16 `bin:"off=0x19, siz=2"` // [ignored-when-writing]
@@ -61,10 +35,20 @@ type DirEntry struct {
}
func (o *DirEntry) UnmarshalBinary(dat []byte) (int, error) {
+ if err := binutil.NeedNBytes(dat, 0x1e); err != nil {
+ return 0, err
+ }
n, err := binstruct.UnmarshalWithoutInterface(dat, o)
if err != nil {
return n, err
}
+ if o.NameLen > MaxNameLen {
+ return 0, fmt.Errorf("maximum name len is %v, but .NameLen=%v",
+ MaxNameLen, o.NameLen)
+ }
+ if err := binutil.NeedNBytes(dat, 0x1e+int(o.DataLen)+int(o.NameLen)); err != nil {
+ return 0, err
+ }
o.Data = dat[n : n+int(o.DataLen)]
n += int(o.DataLen)
o.Name = dat[n : n+int(o.NameLen)]