diff options
author | Luke Shumaker <lukeshu@lukeshu.com> | 2023-02-03 17:25:34 -0700 |
---|---|---|
committer | Luke Shumaker <lukeshu@lukeshu.com> | 2023-02-12 16:16:53 -0700 |
commit | 6386ef96bb6354ed2a588a28080a3ef076736582 (patch) | |
tree | 70d1ba5f650deaf45879c2cd42cd546f06917fd1 | |
parent | 21e92e5dea4d8efc65403eeaee91b32856b86cb6 (diff) |
btrfstree: Add a Pool for byte slices
-rw-r--r-- | lib/btrfs/btrfstree/types_node.go | 11 |
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 |