From a3834e558cf6ae04826b44e65a02ee22286f7952 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Thu, 11 Aug 2016 20:44:07 -0400 Subject: write via temp file avoids short reads, and also if a backup program came along while the write was happening, avoids short backups --- Storage/LocalFiles.hs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'Storage') diff --git a/Storage/LocalFiles.hs b/Storage/LocalFiles.hs index 083a74e..b81ecbe 100644 --- a/Storage/LocalFiles.hs +++ b/Storage/LocalFiles.hs @@ -34,11 +34,14 @@ store :: StorableObjectIdent -> Shard -> IO StoreResult store i s = onError (StoreFailure . show) $ do dir <- shardDir createDirectoryIfMissing True dir - fd <- openFd (dir shardFile i) WriteOnly (Just 0o666) + let dest = dir shardFile i + let tmp = dest ++ ".tmp" + fd <- openFd tmp WriteOnly (Just 0o666) (defaultFileFlags { exclusive = True } ) h <- fdToHandle fd B.hPut h (toByteString s) hClose h + renameFile tmp dest return StoreSuccess retrieve :: ShardNum -> StorableObjectIdent -> IO RetrieveResult @@ -56,6 +59,9 @@ retrieve n i = onError (RetrieveFailure . show) $ do -- There is no way to set the ctime to the epoch, but setting the other -- times does at least set it to the current time, which makes all -- currently stored files look alike. +-- +-- Note that the contents of shards is never changed, so it's ok to set the +-- mtime to the epoch; backup programs won't be confused. obscure :: IO ObscureResult obscure = onError (ObscureFailure . show) $ do dir <- shardDir -- cgit v1.2.3