Skip to content

Commit 3dbdb5b

Browse files
committed
storage: don't buffer tar split file in memory
I cannot see any reason why we should buffer the full tar split content in memory before writing it. That layer is still mark partial at this point and the store is locked so there is no concurrent access either thus we do not need the atomic rename here. Signed-off-by: Paul Holzinger <[email protected]>
1 parent 7ed2bf2 commit 3dbdb5b

File tree

1 file changed

+35
-13
lines changed

1 file changed

+35
-13
lines changed

storage/layers.go

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import (
3131
"go.podman.io/storage/pkg/ioutils"
3232
"go.podman.io/storage/pkg/lockfile"
3333
"go.podman.io/storage/pkg/mount"
34+
"go.podman.io/storage/pkg/pools"
3435
"go.podman.io/storage/pkg/stringid"
3536
"go.podman.io/storage/pkg/system"
3637
"go.podman.io/storage/pkg/tarlog"
@@ -2398,6 +2399,13 @@ func (r *layerStore) ApplyDiff(to string, diff io.Reader) (size int64, err error
23982399
return r.applyDiffWithOptions(to, nil, diff)
23992400
}
24002401

2402+
func createTarSplitFile(r *layerStore, layerID string) (*os.File, error) {
2403+
if err := os.MkdirAll(filepath.Dir(r.tspath(layerID)), 0o700); err != nil {
2404+
return nil, err
2405+
}
2406+
return os.OpenFile(r.tspath(layerID), os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0o600)
2407+
}
2408+
24012409
// Requires startWriting.
24022410
func (r *layerStore) applyDiffWithOptions(to string, layerOptions *LayerOptions, diff io.Reader) (size int64, err error) {
24032411
if !r.lockfile.IsReadWrite() {
@@ -2442,13 +2450,19 @@ func (r *layerStore) applyDiffWithOptions(to string, layerOptions *LayerOptions,
24422450
compressedCounter := ioutils.NewWriteCounter(compressedWriter)
24432451
defragmented = io.TeeReader(defragmented, compressedCounter)
24442452

2445-
tsdata := bytes.Buffer{}
2453+
tarSplitFile, err := createTarSplitFile(r, layer.ID)
2454+
if err != nil {
2455+
return -1, err
2456+
}
2457+
defer tarSplitFile.Close()
2458+
tarSplitWriter := pools.BufioWriter32KPool.Get(tarSplitFile)
2459+
24462460
uidLog := make(map[uint32]struct{})
24472461
gidLog := make(map[uint32]struct{})
24482462
var uncompressedCounter *ioutils.WriteCounter
24492463

24502464
size, err = func() (int64, error) { // A scope for defer
2451-
compressor, err := pgzip.NewWriterLevel(&tsdata, pgzip.BestSpeed)
2465+
compressor, err := pgzip.NewWriterLevel(tarSplitWriter, pgzip.BestSpeed)
24522466
if err != nil {
24532467
return -1, err
24542468
}
@@ -2496,12 +2510,13 @@ func (r *layerStore) applyDiffWithOptions(to string, layerOptions *LayerOptions,
24962510
return -1, err
24972511
}
24982512

2499-
if err := os.MkdirAll(filepath.Dir(r.tspath(layer.ID)), 0o700); err != nil {
2500-
return -1, err
2513+
if err := tarSplitWriter.Flush(); err != nil {
2514+
return -1, fmt.Errorf("failed to flush tar split writer buffer: %w", err)
25012515
}
2502-
if err := ioutils.AtomicWriteFile(r.tspath(layer.ID), tsdata.Bytes(), 0o600); err != nil {
2503-
return -1, err
2516+
if err := tarSplitFile.Sync(); err != nil {
2517+
return -1, fmt.Errorf("sync tar split file: %w", err)
25042518
}
2519+
25052520
if compressedDigester != nil {
25062521
compressedDigest = compressedDigester.Digest()
25072522
}
@@ -2597,10 +2612,16 @@ func (r *layerStore) applyDiffFromStagingDirectory(id string, diffOutput *driver
25972612
}
25982613

25992614
if diffOutput.TarSplit != nil {
2600-
tsdata := bytes.Buffer{}
2601-
compressor, err := pgzip.NewWriterLevel(&tsdata, pgzip.BestSpeed)
2615+
tarSplitFile, err := createTarSplitFile(r, layer.ID)
26022616
if err != nil {
2603-
compressor = pgzip.NewWriter(&tsdata)
2617+
return err
2618+
}
2619+
defer tarSplitFile.Close()
2620+
tarSplitWriter := pools.BufioWriter32KPool.Get(tarSplitFile)
2621+
2622+
compressor, err := pgzip.NewWriterLevel(tarSplitWriter, pgzip.BestSpeed)
2623+
if err != nil {
2624+
compressor = pgzip.NewWriter(tarSplitWriter)
26042625
}
26052626
if _, err := diffOutput.TarSplit.Seek(0, io.SeekStart); err != nil {
26062627
return err
@@ -2614,11 +2635,12 @@ func (r *layerStore) applyDiffFromStagingDirectory(id string, diffOutput *driver
26142635
return err
26152636
}
26162637
compressor.Close()
2617-
if err := os.MkdirAll(filepath.Dir(r.tspath(layer.ID)), 0o700); err != nil {
2618-
return err
2638+
2639+
if err := tarSplitWriter.Flush(); err != nil {
2640+
return fmt.Errorf("failed to flush tar split writer buffer: %w", err)
26192641
}
2620-
if err := ioutils.AtomicWriteFile(r.tspath(layer.ID), tsdata.Bytes(), 0o600); err != nil {
2621-
return err
2642+
if err := tarSplitFile.Sync(); err != nil {
2643+
return fmt.Errorf("sync tar split file: %w", err)
26222644
}
26232645
}
26242646
for k, v := range diffOutput.BigData {

0 commit comments

Comments
 (0)