diff options
Diffstat (limited to 'filesystem/filesystem.go')
| -rw-r--r-- | filesystem/filesystem.go | 37 |
1 files changed, 31 insertions, 6 deletions
diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go index f4f9201..66b3804 100644 --- a/filesystem/filesystem.go +++ b/filesystem/filesystem.go @@ -250,27 +250,52 @@ func (m *Mount) RemoveAllMetadata() error { return m.err(os.Rename(m.BaseDir(), temp.BaseDir())) } +func syncDirectory(dirPath string) error { + dirFile, err := os.Open(dirPath) + if err != nil { + return err + } + if err = dirFile.Sync(); err != nil { + dirFile.Close() + return err + } + return dirFile.Close() +} + // writeDataAtomic writes the data to the path such that the data is either // written to stable storage or an error is returned. func (m *Mount) writeDataAtomic(path string, data []byte) error { - // Write the file to a temporary file then move into place so that the - // operation will be atomic. - tempPath := filepath.Join(filepath.Dir(path), tempPrefix+filepath.Base(path)) - tempFile, err := os.OpenFile(tempPath, os.O_WRONLY|os.O_CREATE, filePermissions) + // Write the data to a temporary file, sync it, then rename into place + // so that the operation will be atomic. + dirPath := filepath.Dir(path) + tempFile, err := ioutil.TempFile(dirPath, tempPrefix) if err != nil { return err } - defer os.Remove(tempPath) + defer os.Remove(tempFile.Name()) + // TempFile() creates the file with mode 0600. Change it to 0644. + if err = tempFile.Chmod(filePermissions); err != nil { + tempFile.Close() + return err + } if _, err = tempFile.Write(data); err != nil { tempFile.Close() return err } + if err = tempFile.Sync(); err != nil { + tempFile.Close() + return err + } if err = tempFile.Close(); err != nil { return err } - return os.Rename(tempPath, path) + if err = os.Rename(tempFile.Name(), path); err != nil { + return err + } + // Ensure the rename has been persisted before returning success. + return syncDirectory(dirPath) } // addMetadata writes the metadata structure to the file with the specified |