summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@lukeshu.com>2023-02-03 17:25:34 -0700
committerLuke Shumaker <lukeshu@lukeshu.com>2023-02-12 16:16:53 -0700
commit6386ef96bb6354ed2a588a28080a3ef076736582 (patch)
tree70d1ba5f650deaf45879c2cd42cd546f06917fd1
parent21e92e5dea4d8efc65403eeaee91b32856b86cb6 (diff)
btrfstree: Add a Pool for byte slices
-rw-r--r--lib/btrfs/btrfstree/types_node.go11
1 files changed, 10 insertions, 1 deletions
diff --git a/lib/btrfs/btrfstree/types_node.go b/lib/btrfs/btrfstree/types_node.go
index 8f8ba0b..de493d6 100644
--- a/lib/btrfs/btrfstree/types_node.go
+++ b/lib/btrfs/btrfstree/types_node.go
@@ -416,6 +416,8 @@ type IOError struct {
func (e *IOError) Error() string { return "i/o error: " + e.Err.Error() }
func (e *IOError) Unwrap() error { return e.Err }
+var bytePool containers.SlicePool[byte]
+
// It is possible that both a non-nil diskio.Ref and an error are
// returned. The error returned (if non-nil) is always of type
// *NodeError[Addr]. Notable errors that may be inside of the
@@ -428,8 +430,9 @@ func ReadNode[Addr ~int64](fs diskio.File[Addr], sb Superblock, addr Addr, exp N
sb.NodeSize, binstruct.StaticSize(NodeHeader{})),
}
}
- nodeBuf := make([]byte, sb.NodeSize)
+ nodeBuf := bytePool.Get(int(sb.NodeSize))
if _, err := fs.ReadAt(nodeBuf, addr); err != nil {
+ bytePool.Put(nodeBuf)
return nil, &NodeError[Addr]{Op: "btrfstree.ReadNode", NodeAddr: addr, Err: &IOError{Err: err}}
}
@@ -453,15 +456,18 @@ func ReadNode[Addr ~int64](fs diskio.File[Addr], sb Superblock, addr Addr, exp N
// sanity checking (that prevents the main parse)
if nodeRef.Data.Head.MetadataUUID != sb.EffectiveMetadataUUID() {
+ bytePool.Put(nodeBuf)
return nodeRef, &NodeError[Addr]{Op: "btrfstree.ReadNode", NodeAddr: addr, Err: ErrNotANode}
}
stored := nodeRef.Data.Head.Checksum
calced, err := nodeRef.Data.ChecksumType.Sum(nodeBuf[binstruct.StaticSize(btrfssum.CSum{}):])
if err != nil {
+ bytePool.Put(nodeBuf)
return nodeRef, &NodeError[Addr]{Op: "btrfstree.ReadNode", NodeAddr: addr, Err: err}
}
if stored != calced {
+ bytePool.Put(nodeBuf)
return nodeRef, &NodeError[Addr]{
Op: "btrfstree.ReadNode", NodeAddr: addr,
Err: fmt.Errorf("looks like a node but is corrupt: checksum mismatch: stored=%v calculated=%v",
@@ -481,9 +487,12 @@ func ReadNode[Addr ~int64](fs diskio.File[Addr], sb Superblock, addr Addr, exp N
// isn't useful.
if _, err := binstruct.Unmarshal(nodeBuf, &nodeRef.Data); err != nil {
+ bytePool.Put(nodeBuf)
return nodeRef, &NodeError[Addr]{Op: "btrfstree.ReadNode", NodeAddr: addr, Err: err}
}
+ bytePool.Put(nodeBuf)
+
// sanity checking (that doesn't prevent parsing)
var errs derror.MultiError