diff options
author | Joey Hess <joey@kitenet.net> | 2013-06-10 13:10:30 -0400 |
---|---|---|
committer | Joey Hess <joey@kitenet.net> | 2013-06-10 13:11:33 -0400 |
commit | a5cb4a7bc5d7d603fc8f5f8b1a1595e889fb25ce (patch) | |
tree | 9b1e97311129413c5e0d33e9b52caa0ab66809dc | |
parent | 7bf5b7b0c5ba2789ef1473329da0000af0410b61 (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.hs | 43 | ||||
-rw-r--r-- | Command/ReKey.hs | 15 | ||||
-rw-r--r-- | Init.hs | 2 | ||||
-rw-r--r-- | Remote/Rsync.hs | 17 | ||||
-rw-r--r-- | Utility/CopyFile.hs | 25 | ||||
-rw-r--r-- | debian/changelog | 8 |
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 @@ -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. |