diff options
author | Joey Hess <joeyh@joeyh.name> | 2017-08-31 14:24:32 -0400 |
---|---|---|
committer | Joey Hess <joeyh@joeyh.name> | 2017-08-31 14:24:32 -0400 |
commit | a7383bc94e41d94e77e67406e1a4085d34241bfc (patch) | |
tree | 4a9dc422ada9ad424bef84dcb7466812e1f51f2f /Remote/Directory.hs | |
parent | 36b222bf699023f3e460c8bc231b2916aa27ab5c (diff) |
make storeExport atomic
This avoids needing to deal with the complexity of partially transferred
files in the export. We'd not be able to resume uploading to such a file
anyway, so just avoid them.
The implementation in Remote.Directory is not completely ideal, because
it could leave the temp file hanging around in the export directory.
This only happens if it's killed with -9, or there's a power failure;
normally viaTmp cleans up after itself, even when interrupted. I could
not see a better way to do it though, since the export directory might
be the root of a filesystem.
Also some design thoughts on resuming, which depend on storeExport being
atomic.
This commit was sponsored by Fernando Jimenez on Partreon.
Diffstat (limited to 'Remote/Directory.hs')
-rw-r--r-- | Remote/Directory.hs | 12 |
1 files changed, 5 insertions, 7 deletions
diff --git a/Remote/Directory.hs b/Remote/Directory.hs index abbde1ceb..f5d7f7e49 100644 --- a/Remote/Directory.hs +++ b/Remote/Directory.hs @@ -29,6 +29,7 @@ import qualified Remote.Directory.LegacyChunked as Legacy import Annex.Content import Annex.UUID import Utility.Metered +import Utility.Tmp remote :: RemoteType remote = RemoteType { @@ -116,11 +117,6 @@ getLocation d k = do storeDir :: FilePath -> Key -> FilePath storeDir d k = addTrailingPathSeparator $ d </> hashDirLower def k </> keyFile k -{- Where we store temporary data for a key, in the directory, as it's being - - written. -} -tmpDir :: FilePath -> Key -> FilePath -tmpDir d k = addTrailingPathSeparator $ d </> "tmp" </> keyFile k - {- Check if there is enough free disk space in the remote's directory to - store the key. Note that the unencrypted key size is checked. -} prepareStore :: FilePath -> ChunkConfig -> Preparer Storer @@ -148,7 +144,7 @@ store d chunkconfig k b p = liftIO $ do finalizeStoreGeneric tmpdir destdir return True where - tmpdir = tmpDir d k + tmpdir = addTrailingPathSeparator $ d </> "tmp" </> keyFile k destdir = storeDir d k {- Passed a temp directory that contains the files that should be placed @@ -233,7 +229,9 @@ checkPresentGeneric d ps = liftIO $ storeExportDirectory :: FilePath -> FilePath -> Key -> ExportLocation -> MeterUpdate -> Annex Bool storeExportDirectory d src _k loc p = liftIO $ catchBoolIO $ do createDirectoryIfMissing True (takeDirectory dest) - withMeteredFile src p (L.writeFile dest) + -- Write via temp file so that checkPresentGeneric will not + -- see it until it's fully stored. + viaTmp (\tmp () -> withMeteredFile src p (L.writeFile tmp)) dest () return True where dest = exportPath d loc |