@@ -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.
24022410func (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