Skip to content

Commit bbb2266

Browse files
committed
storage: fix tar split writer to actually write the full file
The compressor must be closed before we write the bytes. However overall I am not sure why we did write all bytes fully into memory first. So chnage it to directly write to a file but still use a buffer for that to avoid many small writes. Signed-off-by: Paul Holzinger <[email protected]>
1 parent a7a2938 commit bbb2266

File tree

1 file changed

+45
-48
lines changed

1 file changed

+45
-48
lines changed

storage/layers.go

Lines changed: 45 additions & 48 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"
@@ -2452,95 +2453,90 @@ func (r *layerStore) ApplyDiff(to string, diff io.Reader) (size int64, err error
24522453
return r.applyDiffWithOptions(layer, nil, diff)
24532454
}
24542455

2455-
type diffApplyFunc func(id string, parent string, options drivers.ApplyDiffOpts, tsBytes *bytes.Buffer) error
2456+
type diffApplyFunc func(id string, parent string, options drivers.ApplyDiffOpts) error
24562457

24572458
func (r *layerStore) applyDiffUnlocked(dd drivers.ApplyDiffStaging, layer *Layer, layerOptions *LayerOptions, diff io.Reader) ([]tempdir.CleanupTempDirFunc, func() error, int64, error) {
24582459
var (
24592460
size int64
24602461
cleanFunctions []tempdir.CleanupTempDirFunc
2461-
applyDiff func() error
2462+
commit tempdir.CommitFunc
24622463
)
24632464

2464-
f := func(id string, parent string, options drivers.ApplyDiffOpts, tsBytes *bytes.Buffer) error {
2465+
f := func(id string, parent string, options drivers.ApplyDiffOpts) error {
24652466
var (
24662467
err error
24672468
cleanup tempdir.CleanupTempDirFunc
2468-
commit tempdir.CommitFunc
24692469
)
24702470
cleanup, commit, size, err = dd.StartStagingDiffToApply(layer.ID, layer.Parent, options)
24712471
cleanFunctions = append(cleanFunctions, cleanup)
2472+
return err
2473+
}
2474+
2475+
td, err := tempdir.NewTempDir(filepath.Join(r.layerdir, tempDirPath))
2476+
cleanFunctions = append(cleanFunctions, td.Cleanup)
2477+
if err != nil {
2478+
return cleanFunctions, nil, 0, err
2479+
}
2480+
2481+
sa, err := td.StageFileAddition(func(path string) error {
2482+
tsFile, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY, 0o600)
24722483
if err != nil {
24732484
return err
24742485
}
2486+
defer tsFile.Close()
2487+
return r.applyDiffWithOptionsInner(layer, layerOptions, diff, f, tsFile)
2488+
})
2489+
if err != nil {
2490+
return cleanFunctions, nil, 0, err
2491+
}
24752492

2476-
td, err := tempdir.NewTempDir(filepath.Join(r.layerdir, tempDirPath))
2477-
cleanFunctions = append(cleanFunctions, td.Cleanup)
2493+
applyDiff := func() error {
2494+
err := dd.CommitStagedLayer(layer.ID, commit)
24782495
if err != nil {
2479-
return err
2496+
return fmt.Errorf("commit temporary layer: %w", err)
24802497
}
24812498

2482-
sa, err := td.StageFileAddition(func(path string) error {
2483-
return os.WriteFile(path, tsBytes.Bytes(), 0o600)
2484-
})
2485-
cleanFunctions = append(cleanFunctions, td.Cleanup)
2486-
if err != nil {
2499+
if err := os.MkdirAll(filepath.Dir(r.tspath(layer.ID)), 0o700); err != nil {
24872500
return err
24882501
}
24892502

2490-
applyDiff = func() error {
2491-
err := dd.CommitStagedLayer(layer.ID, commit)
2492-
if err != nil {
2493-
return fmt.Errorf("commit temporary layer: %w", err)
2494-
}
2495-
2496-
if err := os.MkdirAll(filepath.Dir(r.tspath(layer.ID)), 0o700); err != nil {
2497-
return err
2498-
}
2499-
2500-
err = sa.Commit(r.tspath(layer.ID))
2501-
if err != nil {
2502-
return fmt.Errorf("commit tar split file: %w", err)
2503-
}
2504-
return nil
2503+
err = sa.Commit(r.tspath(layer.ID))
2504+
if err != nil {
2505+
return fmt.Errorf("commit tar split file: %w", err)
25052506
}
25062507
return nil
25072508
}
25082509

2509-
err := r.applyDiffWithOptionsInner(layer, layerOptions, diff, f)
2510-
if err != nil {
2511-
return cleanFunctions, nil, 0, err
2512-
}
2513-
25142510
return cleanFunctions, applyDiff, size, nil
25152511
}
25162512

25172513
// Requires startWriting.
25182514
func (r *layerStore) applyDiffWithOptions(layer *Layer, layerOptions *LayerOptions, diff io.Reader) (int64, error) {
25192515
var size int64
2520-
f := func(id string, parent string, options drivers.ApplyDiffOpts, tsBytes *bytes.Buffer) error {
2516+
f := func(id string, parent string, options drivers.ApplyDiffOpts) error {
25212517
var err error
25222518
size, err = r.driver.ApplyDiff(layer.ID, layer.Parent, options)
2523-
if err != nil {
2524-
return err
2525-
}
2526-
if err := os.MkdirAll(filepath.Dir(r.tspath(layer.ID)), 0o700); err != nil {
2527-
return err
2528-
}
2529-
if err := ioutils.AtomicWriteFile(r.tspath(layer.ID), tsBytes.Bytes(), 0o600); err != nil {
2530-
return err
2531-
}
2532-
return nil
2519+
return err
25332520
}
25342521

2535-
err := r.applyDiffWithOptionsInner(layer, layerOptions, diff, f)
2522+
if err := os.MkdirAll(filepath.Dir(r.tspath(layer.ID)), 0o700); err != nil {
2523+
return -1, err
2524+
}
2525+
tsFile, err := os.OpenFile(r.tspath(layer.ID), os.O_CREATE|os.O_WRONLY, 0o600)
2526+
if err != nil {
2527+
return -1, err
2528+
}
2529+
defer tsFile.Close()
2530+
2531+
err = r.applyDiffWithOptionsInner(layer, layerOptions, diff, f, tsFile)
25362532
if err != nil {
25372533
return 0, err
25382534
}
25392535

25402536
return size, r.saveFor(layer)
25412537
}
25422538

2543-
func (r *layerStore) applyDiffWithOptionsInner(layer *Layer, layerOptions *LayerOptions, diff io.Reader, applyFunc diffApplyFunc) (err error) {
2539+
func (r *layerStore) applyDiffWithOptionsInner(layer *Layer, layerOptions *LayerOptions, diff io.Reader, applyFunc diffApplyFunc, tsFile *os.File) (err error) {
25442540
if !r.lockfile.IsReadWrite() {
25452541
return fmt.Errorf("not allowed to modify layer contents at %q: %w", r.layerdir, ErrStoreIsReadOnly)
25462542
}
@@ -2578,13 +2574,14 @@ func (r *layerStore) applyDiffWithOptionsInner(layer *Layer, layerOptions *Layer
25782574
compressedCounter := ioutils.NewWriteCounter(compressedWriter)
25792575
defragmented = io.TeeReader(defragmented, compressedCounter)
25802576

2581-
tsdata := bytes.Buffer{}
2577+
tsdata := pools.BufioWriter32KPool.Get(tsFile)
2578+
defer tsdata.Flush()
25822579
uidLog := make(map[uint32]struct{})
25832580
gidLog := make(map[uint32]struct{})
25842581
var uncompressedCounter *ioutils.WriteCounter
25852582

25862583
err = func() error { // A scope for defer
2587-
compressor, err := pgzip.NewWriterLevel(&tsdata, pgzip.BestSpeed)
2584+
compressor, err := pgzip.NewWriterLevel(tsdata, pgzip.BestSpeed)
25882585
if err != nil {
25892586
return err
25902587
}
@@ -2622,7 +2619,7 @@ func (r *layerStore) applyDiffWithOptionsInner(layer *Layer, layerOptions *Layer
26222619
Mappings: r.layerMappings(layer),
26232620
MountLabel: layer.MountLabel,
26242621
}
2625-
return applyFunc(layer.ID, layer.Parent, options, &tsdata)
2622+
return applyFunc(layer.ID, layer.Parent, options)
26262623
}()
26272624
if err != nil {
26282625
return err

0 commit comments

Comments
 (0)