directory CoW on retrieve
authorJoey Hess <joeyh@joeyh.name>
Wed, 14 Apr 2021 18:43:08 +0000 (14:43 -0400)
committerJoey Hess <joeyh@joeyh.name>
Wed, 14 Apr 2021 19:05:12 +0000 (15:05 -0400)
directory: When cp supports reflinks, use it when getting content from a
directory special remote.

Not yet for imports from directory though, and not for store.

Note that, when it's chunked, using cp --reflink would not speed it up, and
when reflink was not supported, would unnecessarily write the chunk to a
file before reading it back in. So, only using a fileRetriever in the
NoChunks case is necessary to keep chunking fast.

fileCopier is told not to verify, because the special remote interface
does not yet support verification in passing. AFAICS, fileCopies can
never return False when not verifying so the added giveup should never
actually happen.

CHANGELOG
Remote/Directory.hs

index 2887c033c99659dbfe663c02879e31b9743089d1..ecbf5e288128bad72f5b6b02a4d2221f73e8763f 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -9,6 +9,8 @@ git-annex (8.20210331) UNRELEASED; urgency=medium
     exporttree remotes in some unusual circumstances.
   * fsck: When downloading content from a remote, if the content is able
     to be verified during the transfer, skip checksumming it a second time.
+  * directory: When cp supports reflinks, use it when getting content from
+    a directory special remote.
 
  -- Joey Hess <id@joeyh.name>  Thu, 01 Apr 2021 12:17:26 -0400
 
index 58c91edfc91a568dfd05b2fbd29bfb7629339d69..cbcbe368e5fbe81382a70d8d1995ce2a275aba22 100644 (file)
@@ -31,6 +31,7 @@ import Remote.Helper.Special
 import Remote.Helper.ExportImport
 import Types.Import
 import qualified Remote.Directory.LegacyChunked as Legacy
+import Annex.CopyFile
 import Annex.Content
 import Annex.Perms
 import Annex.UUID
@@ -67,9 +68,10 @@ gen r u rc gc rs = do
        c <- parsedRemoteConfig remote rc
        cst <- remoteCost gc cheapRemoteCost
        let chunkconfig = getChunkConfig c
+       cow <- liftIO newCopyCoWTried
        return $ Just $ specialRemote c
                (storeKeyM dir chunkconfig)
-               (retrieveKeyFileM dir chunkconfig)
+               (retrieveKeyFileM dir chunkconfig cow)
                (removeKeyM dir)
                (checkPresentM dir chunkconfig)
                Remote
@@ -220,9 +222,13 @@ finalizeStoreGeneric d tmp dest = do
   where
        dest' = fromRawFilePath dest
 
-retrieveKeyFileM :: RawFilePath -> ChunkConfig -> Retriever
-retrieveKeyFileM d (LegacyChunks _) = Legacy.retrieve locations d
-retrieveKeyFileM d _ = byteRetriever $ \k sink ->
+retrieveKeyFileM :: RawFilePath -> ChunkConfig -> CopyCoWTried -> Retriever
+retrieveKeyFileM d (LegacyChunks _) _ = Legacy.retrieve locations d
+retrieveKeyFileM d NoChunks cow = fileRetriever $ \dest k p -> do
+       src <- liftIO $ fromRawFilePath <$> getLocation d k
+       (ok, _verification) <- fileCopier cow src dest k p (return True) NoVerify
+       unless ok $ giveup "failed to copy file from remote"
+retrieveKeyFileM d _ _ = byteRetriever $ \k sink ->
        sink =<< liftIO (L.readFile . fromRawFilePath =<< getLocation d k)
 
 retrieveKeyFileCheapM :: RawFilePath -> ChunkConfig -> Maybe (Key -> AssociatedFile -> FilePath -> Annex ())