mirror of
https://github.com/distribution/distribution.git
synced 2026-02-21 14:22:14 +00:00
fix: sync parent dir to ensure data is reliably stored (#4774)
This commit is contained in:
@@ -9,7 +9,7 @@ import (
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/distribution/distribution/v3/internal/uuid"
|
||||
@@ -164,7 +164,25 @@ func (d *driver) PutContent(ctx context.Context, subPath string, contents []byte
|
||||
dErr := d.Delete(ctx, tempPath)
|
||||
return errors.Join(err, dErr)
|
||||
}
|
||||
return syncDir(filepath.Dir(d.fullPath(subPath)))
|
||||
}
|
||||
|
||||
func syncDir(dir string) (retErr error) {
|
||||
dirF, err := os.Open(dir)
|
||||
if err != nil {
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("sync dir: %w", err)
|
||||
}
|
||||
defer func() {
|
||||
if err := dirF.Close(); err != nil {
|
||||
retErr = errors.Join(retErr, fmt.Errorf("failed to close dir: %w", err))
|
||||
}
|
||||
}()
|
||||
if err := dirF.Sync(); err != nil {
|
||||
return fmt.Errorf("sync dir: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -194,7 +212,7 @@ func (d *driver) Reader(ctx context.Context, path string, offset int64) (io.Read
|
||||
|
||||
func (d *driver) Writer(ctx context.Context, subPath string, append bool) (storagedriver.FileWriter, error) {
|
||||
fullPath := d.fullPath(subPath)
|
||||
parentDir := path.Dir(fullPath)
|
||||
parentDir := filepath.Dir(fullPath)
|
||||
if err := os.MkdirAll(parentDir, 0o777); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -266,7 +284,7 @@ func (d *driver) List(ctx context.Context, subPath string) ([]string, error) {
|
||||
|
||||
keys := make([]string, 0, len(fileNames))
|
||||
for _, fileName := range fileNames {
|
||||
keys = append(keys, path.Join(subPath, fileName))
|
||||
keys = append(keys, filepath.Join(subPath, fileName))
|
||||
}
|
||||
|
||||
return keys, nil
|
||||
@@ -282,7 +300,7 @@ func (d *driver) Move(ctx context.Context, sourcePath string, destPath string) e
|
||||
return storagedriver.PathNotFoundError{Path: sourcePath}
|
||||
}
|
||||
|
||||
if err := os.MkdirAll(path.Dir(dest), 0o777); err != nil {
|
||||
if err := os.MkdirAll(filepath.Dir(dest), 0o777); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -318,7 +336,7 @@ func (d *driver) Walk(ctx context.Context, path string, f storagedriver.WalkFn,
|
||||
|
||||
// fullPath returns the absolute path of a key within the Driver's storage.
|
||||
func (d *driver) fullPath(subPath string) string {
|
||||
return path.Join(d.rootDirectory, subPath)
|
||||
return filepath.Join(d.rootDirectory, subPath)
|
||||
}
|
||||
|
||||
type fileInfo struct {
|
||||
@@ -389,24 +407,27 @@ func (fw *fileWriter) Size() int64 {
|
||||
return fw.size
|
||||
}
|
||||
|
||||
func (fw *fileWriter) Close() error {
|
||||
func (fw *fileWriter) Close() (retErr error) {
|
||||
if fw.closed {
|
||||
return fmt.Errorf("already closed")
|
||||
}
|
||||
fw.closed = true
|
||||
defer func() {
|
||||
if err := fw.file.Close(); err != nil {
|
||||
retErr = errors.Join(retErr, err)
|
||||
}
|
||||
}()
|
||||
|
||||
if fw.committed {
|
||||
// Already flushed and synced
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := fw.bw.Flush(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := fw.file.Sync(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := fw.file.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
fw.closed = true
|
||||
return nil
|
||||
return fw.file.Sync()
|
||||
}
|
||||
|
||||
func (fw *fileWriter) Cancel(ctx context.Context) error {
|
||||
@@ -415,7 +436,8 @@ func (fw *fileWriter) Cancel(ctx context.Context) error {
|
||||
}
|
||||
|
||||
fw.cancelled = true
|
||||
fw.file.Close()
|
||||
fw.closed = true
|
||||
_ = fw.file.Close()
|
||||
return os.Remove(fw.file.Name())
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user