revert change that broke test_readonly

commit 63d508e885 broke test_readonly.
When a local git remote is readonly, tryCopyCoW run to copy a file
from it failed at withOtherTmp.

Sponsored-by: Dartmouth College's Datalad project
This commit is contained in:
Joey Hess 2021-09-27 15:53:12 -04:00
parent a92427c0d3
commit 7ccf642863
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
4 changed files with 10 additions and 27 deletions

View file

@ -15,8 +15,6 @@ import Utility.CopyFile
import Utility.FileMode
import Utility.Touch
import Utility.Hash (IncrementalVerifier(..))
import Annex.Tmp
import Utility.Tmp
import Control.Concurrent
import qualified Data.ByteString as S
@ -30,34 +28,23 @@ newCopyCoWTried :: IO CopyCoWTried
newCopyCoWTried = CopyCoWTried <$> newEmptyMVar
{- Copies a file is copy-on-write is supported. Otherwise, returns False. -}
tryCopyCoW :: CopyCoWTried -> FilePath -> FilePath -> MeterUpdate -> Annex Bool
tryCopyCoW :: CopyCoWTried -> FilePath -> FilePath -> MeterUpdate -> IO Bool
tryCopyCoW (CopyCoWTried copycowtried) src dest meterupdate =
-- If multiple threads reach this at the same time, they
-- will both try CoW, which is acceptable.
ifM (liftIO $ isEmptyMVar copycowtried)
ifM (isEmptyMVar copycowtried)
( do
ok <- docopycow
void $ liftIO $ tryPutMVar copycowtried ok
void $ tryPutMVar copycowtried ok
return ok
, ifM (liftIO $ readMVar copycowtried)
, ifM (readMVar copycowtried)
( docopycow
, return False
)
)
where
-- copyCow needs a destination file that does not exist,
-- but the dest file might already. So use it with another
-- temp file, and if it succeeds, rename it into place. If it fails,
-- the dest file is left as-is, to support resuming.
docopycow = withOtherTmp $ \othertmp -> liftIO $
withTmpFileIn (fromRawFilePath othertmp) (takeFileName dest) $ \tmpdest _h -> do
copied <- watchFileSize tmpdest meterupdate $
copyCoW CopyTimeStamps src tmpdest
if copied
then liftIO $ catchBoolIO $ do
rename tmpdest dest
return True
else return False
docopycow = watchFileSize dest meterupdate $
copyCoW CopyTimeStamps src dest
data CopyMethod = CopiedCoW | Copied
@ -83,7 +70,7 @@ fileCopier :: CopyCoWTried -> FilePath -> FilePath -> MeterUpdate -> Maybe Incre
fileCopier _ src dest meterupdate iv = docopy
#else
fileCopier copycowtried src dest meterupdate iv =
ifM (tryCopyCoW copycowtried src dest meterupdate)
ifM (liftIO $ tryCopyCoW copycowtried src dest meterupdate)
( do
liftIO $ maybe noop unableIncremental iv
return CopiedCoW

View file

@ -8,8 +8,6 @@ git-annex (8.20210904) UNRELEASED; urgency=medium
(Reversion in version 4.20130323)
* borg: Avoid trying to extract xattrs, ACLS, and bsdflags when
retrieving from a borg repository.
* Resume where it left off when copying a file to/from a local git remote
was interrupted.
* Sped up git-annex smudge --clean by 25%.
-- Joey Hess <id@joeyh.name> Fri, 03 Sep 2021 12:02:55 -0400

View file

@ -412,7 +412,7 @@ retrieveExportWithContentIdentifierM dir cow loc cid dest mkkey p =
f = exportPath dir loc
f' = fromRawFilePath f
docopy = ifM (tryCopyCoW cow f' dest p)
docopy = ifM (liftIO $ tryCopyCoW cow f' dest p)
( do
k <- mkkey
postcheckcow (return k)

View file

@ -56,13 +56,11 @@ copyFileExternal meta src dest = do
| otherwise = copyMetaDataParams meta
{- When a filesystem supports CoW (and cp does), uses it to make
- an efficient copy of a file. Otherwise, returns False.
-
- The dest file must not exist yet, or it will fail to make a CoW copy,
- and will return False. -}
- an efficient copy of a file. Otherwise, returns False. -}
copyCoW :: CopyMetaData -> FilePath -> FilePath -> IO Bool
copyCoW meta src dest
| BuildInfo.cp_reflink_supported = do
void $ tryIO $ removeFile dest
-- When CoW is not supported, cp will complain to stderr,
-- so have to discard its stderr.
ok <- catchBoolIO $ withNullHandle $ \nullh ->