summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Joey Hess <joey@kitenet.net>2013-06-10 13:10:30 -0400
committerGravatar Joey Hess <joey@kitenet.net>2013-06-10 13:11:33 -0400
commita5cb4a7bc5d7d603fc8f5f8b1a1595e889fb25ce (patch)
tree9b1e97311129413c5e0d33e9b52caa0ab66809dc
parent7bf5b7b0c5ba2789ef1473329da0000af0410b61 (diff)
Supports indirect mode on encfs in paranoia mode, and other filesystems that do not support hard links, but do support symlinks and other POSIX filesystem features.
-rw-r--r--Command/Add.hs43
-rw-r--r--Command/ReKey.hs15
-rw-r--r--Init.hs2
-rw-r--r--Remote/Rsync.hs17
-rw-r--r--Utility/CopyFile.hs25
-rw-r--r--debian/changelog8
6 files changed, 65 insertions, 45 deletions
diff --git a/Command/Add.hs b/Command/Add.hs
index fe1a6b13a..6a2261d1f 100644
--- a/Command/Add.hs
+++ b/Command/Add.hs
@@ -80,20 +80,21 @@ start file = ifAnnexed file addpresent add
{- The file that's being added is locked down before a key is generated,
- to prevent it from being modified in between. It's hard linked into a
- - temporary location, and its writable bits are removed. It could still be
- - written to by a process that already has it open for writing.
+ - temporary location (to prevent it being replaced with another file),
+ - and its writable bits are removed. It could still be written to by a
+ - process that already has it open for writing.
+ -
+ - On a crippled filesystem, no lock down is done; the file can be modified
+ - at any time, and the no hard link is made.
+ -
+ - On a filesystem without hard links, but not otherwise crippled,
+ - no hard link is made, but the write bit is still removed.
-
- Lockdown can fail if a file gets deleted, and Nothing will be returned.
-}
lockDown :: FilePath -> Annex (Maybe KeySource)
lockDown file = ifM (crippledFileSystem)
- ( liftIO $ catchMaybeIO $ do
- cache <- genInodeCache file
- return $ KeySource
- { keyFilename = file
- , contentLocation = file
- , inodeCache = cache
- }
+ ( liftIO $ catchMaybeIO nohardlink
, do
tmp <- fromRepo gitAnnexTmpDir
createAnnexDirectory tmp
@@ -102,14 +103,24 @@ lockDown file = ifM (crippledFileSystem)
(tmpfile, h) <- openTempFile tmp (takeFileName file)
hClose h
nukeFile tmpfile
- createLink file tmpfile
- cache <- genInodeCache tmpfile
- return $ KeySource
- { keyFilename = file
- , contentLocation = tmpfile
- , inodeCache = cache
- }
+ withhardlink tmpfile `catchIO` const nohardlink
)
+ where
+ nohardlink = do
+ cache <- genInodeCache file
+ return $ KeySource
+ { keyFilename = file
+ , contentLocation = file
+ , inodeCache = cache
+ }
+ withhardlink tmpfile = do
+ createLink file tmpfile
+ cache <- genInodeCache tmpfile
+ return $ KeySource
+ { keyFilename = file
+ , contentLocation = tmpfile
+ , inodeCache = cache
+ }
{- Ingests a locked down file into the annex.
-
diff --git a/Command/ReKey.hs b/Command/ReKey.hs
index 05fd73f1b..d7b277fa6 100644
--- a/Command/ReKey.hs
+++ b/Command/ReKey.hs
@@ -7,8 +7,6 @@
module Command.ReKey where
-import System.PosixCompat.Files
-
import Common.Annex
import Command
import qualified Annex
@@ -17,7 +15,6 @@ import Annex.Content
import qualified Command.Add
import Logs.Web
import Logs.Location
-import Config
import Utility.CopyFile
def :: [Command]
@@ -49,18 +46,14 @@ perform file oldkey newkey = do
return True
next $ cleanup file oldkey newkey
-{- Make a hard link to the old key content, to avoid wasting disk space. -}
+{- Make a hard link to the old key content (when supported),
+ - to avoid wasting disk space. -}
linkKey :: Key -> Key -> Annex Bool
linkKey oldkey newkey = getViaTmpUnchecked newkey $ \tmp -> do
src <- calcRepo $ gitAnnexLocation oldkey
- ifM (liftIO $ doesFileExist tmp)
+ liftIO $ ifM (doesFileExist tmp)
( return True
- , ifM crippledFileSystem
- ( liftIO $ copyFileExternal src tmp
- , do
- liftIO $ createLink src tmp
- return True
- )
+ , createLinkOrCopy src tmp
)
cleanup :: FilePath -> Key -> Key -> CommandCleanup
diff --git a/Init.hs b/Init.hs
index 6409fe9c4..09e80eebd 100644
--- a/Init.hs
+++ b/Init.hs
@@ -140,8 +140,6 @@ probeCrippledFileSystem = do
probe f = catchBoolIO $ do
let f2 = f ++ "2"
nukeFile f2
- createLink f f2
- nukeFile f2
createSymbolicLink f f2
nukeFile f2
preventWrite f
diff --git a/Remote/Rsync.hs b/Remote/Rsync.hs
index f7abbbf2a..228a66d51 100644
--- a/Remote/Rsync.hs
+++ b/Remote/Rsync.hs
@@ -264,7 +264,7 @@ rsyncRemote o callback params = do
-
- This would not be necessary if the hash directory structure used locally
- was always the same as that used on the rsync remote. So if that's ever
- - unified, this gets nicer. Especially in the crippled filesystem case.
+ - unified, this gets nicer.
- (When we have the right hash directory structure, we can just
- pass --include=X --include=X/Y --include=X/Y/file --exclude=*)
-}
@@ -272,20 +272,11 @@ rsyncSend :: RsyncOpts -> MeterUpdate -> Key -> Bool -> FilePath -> Annex Bool
rsyncSend o callback k canrename src = withRsyncScratchDir $ \tmp -> do
let dest = tmp </> Prelude.head (keyPaths k)
liftIO $ createDirectoryIfMissing True $ parentDir dest
- ok <- if canrename
+ ok <- liftIO $ if canrename
then do
- liftIO $ renameFile src dest
+ renameFile src dest
return True
- else ifM crippledFileSystem
- ( liftIO $ copyFileExternal src dest
- , do
-#ifndef __WINDOWS__
- liftIO $ createLink src dest
- return True
-#else
- liftIO $ copyFileExternal src dest
-#endif
- )
+ else createLinkOrCopy src dest
ps <- sendParams
if ok
then rsyncRemote o (Just callback) $ ps ++
diff --git a/Utility/CopyFile.hs b/Utility/CopyFile.hs
index 18290669d..bb0600aa9 100644
--- a/Utility/CopyFile.hs
+++ b/Utility/CopyFile.hs
@@ -1,11 +1,16 @@
-{- git-annex file copying
+{- file copying
-
- - Copyright 2010,2012 Joey Hess <joey@kitenet.net>
+ - Copyright 2010-2013 Joey Hess <joey@kitenet.net>
-
- Licensed under the GNU GPL version 3 or higher.
-}
-module Utility.CopyFile (copyFileExternal) where
+{-# LANGUAGE CPP #-}
+
+module Utility.CopyFile (
+ copyFileExternal,
+ createLinkOrCopy
+) where
import Common
import qualified Build.SysConfig as SysConfig
@@ -23,3 +28,17 @@ copyFileExternal src dest = do
, (SysConfig.cp_a, Param "-a")
, (SysConfig.cp_p && not SysConfig.cp_a, Param "-p")
]
+
+{- Create a hard link if the filesystem allows it, and fall back to copying
+ - the file. -}
+createLinkOrCopy :: FilePath -> FilePath -> IO Bool
+#ifndef __WINDOWS__
+createLinkOrCopy src dest = go `catchIO` const fallback
+ where
+ go = do
+ createLink src dest
+ return True
+ fallback = copyFileExternal src dest
+#else
+createLinkOrCopy = copyFileExternal
+#endif
diff --git a/debian/changelog b/debian/changelog
index 3b696fe84..f5a8f5128 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,11 @@
+git-annex (4.20130602) UNRELEASED; urgency=low
+
+ * Supports indirect mode on encfs in paranoia mode, and other
+ filesystems that do not support hard links, but do support
+ symlinks and other POSIX filesystem features.
+
+ -- Joey Hess <joeyh@debian.org> Mon, 10 Jun 2013 12:52:44 -0400
+
git-annex (4.20130601) unstable; urgency=medium
* XMPP: Git push over xmpp made much more robust.