summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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.