From 6386ef96bb6354ed2a588a28080a3ef076736582 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Fri, 3 Feb 2023 17:25:34 -0700 Subject: btrfstree: Add a Pool for byte slices --- lib/btrfs/btrfstree/types_node.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'lib/btrfs/btrfstree/types_node.go') 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 -- cgit v1.2.3-54-g00ecf