summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Joey Hess <joey@kitenet.net>2012-01-16 16:28:07 -0400
committerGravatar Joey Hess <joey@kitenet.net>2012-01-16 16:28:15 -0400
commitf161b5eb596839d54c006a68e875088a9d66c105 (patch)
tree6d5cbdd08c7a100cb6da871963ab6e142f8ab59e
parent0c4f12e8a2742dc6f7703822034152ecb518e2cc (diff)
Fix data loss bug in directory special remote
When moving a file to the remote failed, and partially transferred content was left behind in the directory, re-running the same move would think it succeeded and delete the local copy. I reproduced data loss when moving files to a partition that was almost full. Interrupting a transfer could have similar results. Easily fixed by using a temp file which is then moved atomically into place once the transfer completes. I've audited other calls to copyFileExternal, and other special remote file transfer code; everything else seems to use temp files correctly (rsync, git), or otherwise use atomic transfers (bup, S3).
-rw-r--r--Remote/Directory.hs4
-rw-r--r--debian/changelog9
2 files changed, 12 insertions, 1 deletions
diff --git a/Remote/Directory.hs b/Remote/Directory.hs
index 8ca2a2875..23265dabc 100644
--- a/Remote/Directory.hs
+++ b/Remote/Directory.hs
@@ -98,11 +98,13 @@ storeEncrypted d (cipher, enck) k = do
storeHelper :: FilePath -> Key -> (FilePath -> IO Bool) -> IO Bool
storeHelper d key a = do
let dest = Prelude.head $ locations d key
+ let tmpdest = dest ++ ".tmp"
let dir = parentDir dest
createDirectoryIfMissing True dir
allowWrite dir
- ok <- a dest
+ ok <- a tmpdest
when ok $ do
+ renameFile tmpdest dest
preventWrite dest
preventWrite dir
return ok
diff --git a/debian/changelog b/debian/changelog
index 17816dc1a..61922ae05 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,12 @@
+git-annex (3.20120116) UNRELEASED; urgency=low
+
+ * Fix data loss bug in directory special remote, when moving a file
+ to the remote failed, and partially transferred content was left
+ behind in the directory, re-running the same move would think it
+ succeeded and delete the local copy.
+
+ -- Joey Hess <joeyh@debian.org> Mon, 16 Jan 2012 16:21:51 -0400
+
git-annex (3.20120115) unstable; urgency=low
* Add a sanity check for bad StatFS results. On architectures