diff --git a/pkg/local_object_storage/blobstor/fstree/head.go b/pkg/local_object_storage/blobstor/fstree/head.go index d05db9ec80..3861187bf3 100644 --- a/pkg/local_object_storage/blobstor/fstree/head.go +++ b/pkg/local_object_storage/blobstor/fstree/head.go @@ -146,19 +146,22 @@ func (t *FSTree) readHeaderAndPayload(f io.ReadCloser, initial []byte) (*object. // and returns the object along with a reader for the remaining data. // This function takes ownership of the io.ReadCloser and will close it if it does not return it. func (t *FSTree) readUntilPayload(f io.ReadCloser, initial []byte) (*object.Object, io.ReadSeekCloser, error) { - reader := f + reader := io.Reader(f) + closer := io.Closer(f) if t.IsCompressed(initial) { decoder, err := zstd.NewReader(io.MultiReader(bytes.NewReader(initial), f)) if err != nil { + _ = closer.Close() return nil, nil, fmt.Errorf("zstd decoder: %w", err) } - reader = decoder.IOReadCloser() + reader = decoder + closer = zstdCloser{dec: decoder, cls: closer} buf := make([]byte, object.MaxHeaderLen) n, err := decoder.Read(buf) if err != nil && !errors.Is(err, io.EOF) { - decoder.Close() + closer.Close() return nil, nil, fmt.Errorf("zstd read: %w", err) } initial = buf[:n] @@ -166,13 +169,13 @@ func (t *FSTree) readUntilPayload(f io.ReadCloser, initial []byte) (*object.Obje obj, payloadPrefix, err := objectwire.ExtractHeaderAndPayload(initial) if err != nil { - _ = reader.Close() + _ = closer.Close() return nil, nil, fmt.Errorf("extract header and payload: %w", err) } return obj, &payloadReader{ Reader: io.MultiReader(bytes.NewReader(payloadPrefix), reader), - close: reader.Close, + close: closer.Close, }, nil } diff --git a/pkg/local_object_storage/blobstor/fstree/util.go b/pkg/local_object_storage/blobstor/fstree/util.go new file mode 100644 index 0000000000..75d6187343 --- /dev/null +++ b/pkg/local_object_storage/blobstor/fstree/util.go @@ -0,0 +1,17 @@ +package fstree + +import ( + "io" + + "github.com/klauspost/compress/zstd" +) + +type zstdCloser struct { + dec *zstd.Decoder + cls io.Closer +} + +func (x zstdCloser) Close() error { + x.dec.Close() + return x.cls.Close() +}