From b4f2af3f60f386b3415f1ff24e07fbc4eb6b4217 Mon Sep 17 00:00:00 2001 From: ningmingxiao Date: Fri, 30 Jan 2026 18:53:43 +0800 Subject: [PATCH] fix: sync parent dir to ensure data is reliably stored Co-authored-by: Sebastiaan van Stijn Signed-off-by: ningmingxiao Signed-off-by: Sebastiaan van Stijn --- registry/storage/driver/filesystem/driver.go | 44 +++++++++++++++----- 1 file changed, 33 insertions(+), 11 deletions(-) diff --git a/registry/storage/driver/filesystem/driver.go b/registry/storage/driver/filesystem/driver.go index f40dd32c6..1b72f32b9 100644 --- a/registry/storage/driver/filesystem/driver.go +++ b/registry/storage/driver/filesystem/driver.go @@ -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 } @@ -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()) }