Only use cp -a if it is supported, falling back to cp -p or plain cp.

* cp --reflink=auto is used if supported, and will make git annex unlock
  much faster on filesystems like btrfs that support copy of write.
This commit is contained in:
Joey Hess 2010-11-18 13:48:28 -04:00
parent 54513c69ba
commit 161823d6ea
7 changed files with 48 additions and 18 deletions

View file

@ -8,7 +8,7 @@
module Command.Unlock where module Command.Unlock where
import Control.Monad.State (liftIO) import Control.Monad.State (liftIO)
import System.Directory import System.Directory hiding (copyFile)
import Command import Command
import qualified Annex import qualified Annex
@ -17,6 +17,7 @@ import Messages
import Locations import Locations
import Utility import Utility
import Core import Core
import CopyFile
seek :: [SubCmdSeek] seek :: [SubCmdSeek]
seek = [withFilesInGit start] seek = [withFilesInGit start]
@ -34,9 +35,9 @@ perform dest key = do
let src = annexLocation g key let src = annexLocation g key
liftIO $ removeFile dest liftIO $ removeFile dest
showNote "copying..." showNote "copying..."
ok <- liftIO $ boolSystem "cp" ["-p", src, dest] ok <- liftIO $ copyFile src dest
if ok if ok
then do then do
liftIO $ allowWrite dest liftIO $ allowWrite dest
return $ Just $ return True return $ Just $ return True
else error "cp failed!" else error "copy failed!"

24
CopyFile.hs Normal file
View file

@ -0,0 +1,24 @@
{- git-annex file copying
-
- Copyright 2010 Joey Hess <joey@kitenet.net>
-
- Licensed under the GNU GPL version 3 or higher.
-}
module CopyFile (copyFile) where
import Utility
import qualified SysConfig
{- The cp command is used, because I hate reinventing the wheel,
- and because this allows easy access to features like cp --reflink. -}
copyFile :: FilePath -> FilePath -> IO Bool
copyFile src dest = boolSystem "cp" opts
where
opts = if (SysConfig.cp_reflink_auto)
then ["--reflink=auto", src, dest]
else if (SysConfig.cp_a)
then ["-a", src, dest]
else if (SysConfig.cp_p)
then ["-p", src, dest]
else [src, dest]

View file

@ -2,7 +2,7 @@ all: git-annex docs
ghcmake=ghc -Wall -odir build -hidir build -O2 --make ghcmake=ghc -Wall -odir build -hidir build -O2 --make
SysConfig.hs: SysConfig.hs: configure.hs
$(ghcmake) configure $(ghcmake) configure
./configure ./configure

View file

@ -23,7 +23,7 @@ import Control.Monad.State (liftIO)
import Control.Monad (filterM) import Control.Monad (filterM)
import qualified Data.Map as Map import qualified Data.Map as Map
import Data.String.Utils import Data.String.Utils
import System.Directory import System.Directory hiding (copyFile)
import System.Posix.Directory import System.Posix.Directory
import List import List
import Monad (when, unless) import Monad (when, unless)
@ -37,6 +37,7 @@ import UUID
import Utility import Utility
import qualified Core import qualified Core
import Messages import Messages
import CopyFile
{- Human visible list of remotes. -} {- Human visible list of remotes. -}
list :: [Git.Repo] -> String list :: [Git.Repo] -> String
@ -204,7 +205,7 @@ copyFromRemote r key file = do
then getssh then getssh
else error "copying from non-ssh repo not supported" else error "copying from non-ssh repo not supported"
where where
getlocal = liftIO $ boolSystem "cp" ["-a", keyloc, file] getlocal = liftIO $ copyFile keyloc file
getssh = scp r [sshLocation r keyloc, file] getssh = scp r [sshLocation r keyloc, file]
keyloc = annexLocation r key keyloc = annexLocation r key
@ -219,7 +220,7 @@ copyToRemote r key file = do
then putssh keyloc then putssh keyloc
else error "copying to non-ssh repo not supported" else error "copying to non-ssh repo not supported"
where where
putlocal src = liftIO $ boolSystem "cp" ["-a", src, file] putlocal src = liftIO $ copyFile src file
putssh src = scp r [src, sshLocation r file] putssh src = scp r [src, sshLocation r file]
sshLocation :: Git.Repo -> FilePath -> FilePath sshLocation :: Git.Repo -> FilePath -> FilePath

View file

@ -1,5 +1,4 @@
{- Checks system configuration and generates SysConfig.hs. {- Checks system configuration and generates SysConfig.hs. -}
-}
import System.IO import System.IO
import System.Cmd import System.Cmd
@ -12,8 +11,9 @@ data Config = Config String Bool
tests :: [TestDesc] tests :: [TestDesc]
tests = [ tests = [
TestDesc "cp -a" "cp_a" cp_a TestDesc "cp -a" "cp_a" $ testCp "-a"
, TestDesc "cp --reflink" "cp_reflink" cp_reflink , TestDesc "cp -p" "cp_p" $ testCp "-p"
, TestDesc "cp --reflink=auto" "cp_reflink_auto" $ testCp "--reflink=auto"
] ]
tmpDir :: String tmpDir :: String
@ -25,11 +25,9 @@ testFile = tmpDir ++ "/testfile"
quiet :: String -> String quiet :: String -> String
quiet s = s ++ " 2>/dev/null" quiet s = s ++ " 2>/dev/null"
cp_a :: Test testCp :: String -> Test
cp_a = testCmd $ quiet $ "cp -a " ++ testFile ++ " " ++ testFile ++ ".new" testCp option = testCmd $ quiet $ "cp " ++ option ++ " " ++ testFile ++
" " ++ testFile ++ ".new"
cp_reflink :: Test
cp_reflink = testCmd $ quiet $ "cp --reflink=auto " ++ testFile ++ " " ++ testFile ++ ".new"
testCmd :: String -> Test testCmd :: String -> Test
testCmd c = do testCmd c = do
@ -51,6 +49,7 @@ writeSysConfig config = do
header = [ header = [
"{- Automatically generated by configure. -}" "{- Automatically generated by configure. -}"
, "module SysConfig where" , "module SysConfig where"
, ""
] ]
footer = [] footer = []
vars [] = [] vars [] = []
@ -58,6 +57,7 @@ writeSysConfig config = do
showvar (Config name val) = [ showvar (Config name val) = [
name ++ " :: Bool" name ++ " :: Bool"
, name ++ " = " ++ show val , name ++ " = " ++ show val
, ""
] ]
runTests :: [TestDesc] -> IO [Config] runTests :: [TestDesc] -> IO [Config]

6
debian/changelog vendored
View file

@ -2,8 +2,10 @@ git-annex (0.08) UNRELEASED; urgency=low
* Fix `git annex add ../foo` (when ran in a subdir of the repo). * Fix `git annex add ../foo` (when ran in a subdir of the repo).
* Add configure step to build process. * Add configure step to build process.
* configure: Check to see if cp -a can be used. * Only use cp -a if it is supported, falling back to cp -p or plain cp
* configure: Check to see if cp --reflink=auto can be used. as needed for portability.
* cp --reflink=auto is used if supported, and will make git annex unlock
much faster on filesystems like btrfs that support copy of write.
-- Joey Hess <joeyh@debian.org> Wed, 17 Nov 2010 13:54:49 -0400 -- Joey Hess <joeyh@debian.org> Wed, 17 Nov 2010 13:54:49 -0400

View file

@ -3,3 +3,5 @@ The unlock command needs to copy a file, and it would be great to use this:
O(1) overhead on BTRFS. Needs coreutils 7.6; and remember that git-annex O(1) overhead on BTRFS. Needs coreutils 7.6; and remember that git-annex
may be used on systems without coreutils.. may be used on systems without coreutils..
[[done]]