return nil
}
+
+// writeFileDurable replaces path only after syncing its private temporary file.
+// It syncs the directory after rename before it reports success. An error after
+// rename has an uncertain outcome, so callers must stop writes until recovery.
+func writeFileDurable(path string, data []byte) (err error) {
+ file, err := os.CreateTemp(filepath.Dir(path), "."+filepath.Base(path)+".*")
+ if err != nil {
+ return fmt.Errorf("create durable temporary file: %w", err)
+ }
+
+ defer func() {
+ removeErr := os.Remove(file.Name())
+ if removeErr != nil && !errors.Is(removeErr, os.ErrNotExist) {
+ err = errors.Join(err, fmt.Errorf("remove durable temporary file: %w", removeErr))
+ }
+ }()
+
+ _, err = file.Write(data)
+ if err == nil {
+ err = file.Sync()
+ }
+
+ err = errors.Join(err, file.Close())
+ if err != nil {
+ return fmt.Errorf("write durable temporary file: %w", err)
+ }
+
+ err = os.Rename(file.Name(), path)
+ if err != nil {
+ return fmt.Errorf("publish durable file: %w", err)
+ }
+
+ directory, err := os.Open(filepath.Dir(path))
+ if err != nil {
+ return fmt.Errorf("open durable directory: %w", err)
+ }
+
+ err = errors.Join(directory.Sync(), directory.Close())
+ if err != nil {
+ return fmt.Errorf("sync durable directory: %w", err)
+ }
+
+ return nil
+}