summaryrefslogtreecommitdiff
path: root/pkg
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@lukeshu.com>2022-06-04 20:19:37 -0600
committerLuke Shumaker <lukeshu@lukeshu.com>2022-06-04 20:19:37 -0600
commit02fccc8c29d6f638efee0302868242d805bd7711 (patch)
treeac0828229ec4e3cca23562e517530a0806160264 /pkg
parent95f1e4c2010fe8fd2a5537904f99082afbd20bf6 (diff)
Preserve padding
Diffstat (limited to 'pkg')
-rw-r--r--pkg/btrfs/types_btree.go15
-rw-r--r--pkg/btrfs/util.go7
2 files changed, 21 insertions, 1 deletions
diff --git a/pkg/btrfs/types_btree.go b/pkg/btrfs/types_btree.go
index f609b8c..0be7b48 100644
--- a/pkg/btrfs/types_btree.go
+++ b/pkg/btrfs/types_btree.go
@@ -20,6 +20,8 @@ type Node struct {
// the node's type, as specified in the header)
BodyInternal []KeyPointer // for internal nodes
BodyLeaf []Item // for leave nodes
+
+ Padding []byte
}
type NodeHeader struct {
@@ -118,9 +120,11 @@ func (node *Node) UnmarshalBinary(nodeBuf []byte) (int, error) {
}
node.BodyInternal = append(node.BodyInternal, item)
}
- return n, nil
+ node.Padding = nodeBuf[n:]
+ return len(nodeBuf), nil
} else {
// leaf node
+ firstRead := len(nodeBuf)
lastRead := 0
for i := uint32(0); i < node.Head.NumItems; i++ {
var item Item
@@ -137,11 +141,13 @@ func (node *Node) UnmarshalBinary(nodeBuf []byte) (int, error) {
dataOff+dataSize, len(nodeBuf))
}
dataBuf := nodeBuf[dataOff : dataOff+dataSize]
+ firstRead = min(firstRead, dataOff)
lastRead = max(lastRead, dataOff+dataSize)
item.Body = btrfsitem.UnmarshalItem(item.Head.Key.ItemType, dataBuf)
node.BodyLeaf = append(node.BodyLeaf, item)
}
+ node.Padding = nodeBuf[n:firstRead]
return max(n, lastRead), nil
}
}
@@ -166,6 +172,7 @@ func (node Node) MarshalBinary() ([]byte, error) {
return dat, err
}
}
+ dat = append(dat, node.Padding...)
if copy(ret, dat) < len(dat) {
return ret, fmt.Errorf("btrfs.Node.MarshalBinary: need at least %d bytes, but .Size is only %d",
len(dat), node.Size)
@@ -177,6 +184,7 @@ func (node Node) MarshalBinary() ([]byte, error) {
len(dat), node.Size)
}
n := len(dat)
+ minData := len(ret)
for _, item := range node.BodyLeaf {
dat, err = binstruct.Marshal(item.Head)
if err != nil {
@@ -193,11 +201,16 @@ func (node Node) MarshalBinary() ([]byte, error) {
return ret, err
}
dataOff := binstruct.StaticSize(NodeHeader{}) + int(item.Head.DataOffset)
+ minData = min(minData, dataOff)
if copy(ret[dataOff:], dat) < len(dat) {
return ret, fmt.Errorf("btrfs.Node.MarshalBinary: need at least %d bytes, but .Size is only %d",
dataOff+len(dat), node.Size)
}
}
+ if copy(ret[n:minData], node.Padding) < len(node.Padding) {
+ return ret, fmt.Errorf("btrfs.Node.MarshalBinary: not enough room left for padding")
+ }
+
}
return ret, nil
}
diff --git a/pkg/btrfs/util.go b/pkg/btrfs/util.go
index 312ec75..671d6fc 100644
--- a/pkg/btrfs/util.go
+++ b/pkg/btrfs/util.go
@@ -19,3 +19,10 @@ func max[T constraints.Ordered](a, b T) T {
}
return b
}
+
+func min[T constraints.Ordered](a, b T) T {
+ if a < b {
+ return a
+ }
+ return b
+}