check inode cache in prepSendAnnex
authorJoey Hess <joeyh@joeyh.name>
Thu, 10 Dec 2015 18:29:34 +0000 (14:29 -0400)
committerJoey Hess <joeyh@joeyh.name>
Thu, 10 Dec 2015 18:50:52 +0000 (14:50 -0400)
This does mean one query of the database every time an object is sent.
May impact performance.

Annex/Content.hs
Remote/Git.hs
doc/todo/smudge.mdwn

index 12859c856eb91af1a18d7b1427488811f76863e8..bfc70ac9a8ee30d8e347d836dbf7deecdeb3fc93 100644 (file)
@@ -518,7 +518,7 @@ data LinkAnnexResult = LinkAnnexOk | LinkAnnexFailed | LinkAnnexNoop
 
 {- Runs an action to transfer an object's content.
  -
- - In direct mode, it's possible for the file to change as it's being sent.
+ - In some cases, it's possible for the file to change as it's being sent.
  - If this happens, runs the rollback action and returns False. The
  - rollback action should remove the data that was transferred.
  -}
@@ -538,8 +538,9 @@ sendAnnex key rollback sendobject = go =<< prepSendAnnex key
 {- Returns a file that contains an object's content,
  - and a check to run after the transfer is complete.
  -
- - In direct mode, it's possible for the file to change as it's being sent,
- - and the check detects this case and returns False.
+ - When a file is unlocked (or in direct mode), it's possble for its
+ - content to change as it's being sent. The check detects this case
+ - and returns False.
  -
  - Note that the returned check action is, in some cases, run in the
  - Annex monad of the remote that is receiving the object, rather than
@@ -548,13 +549,26 @@ sendAnnex key rollback sendobject = go =<< prepSendAnnex key
 prepSendAnnex :: Key -> Annex (Maybe (FilePath, Annex Bool))
 prepSendAnnex key = withObjectLoc key indirect direct
   where
-       indirect f = return $ Just (f, return True)
+       indirect f = do
+               cache <- Database.Keys.getInodeCaches key
+               cache' <- if null cache
+                       -- Since no inode cache is in the database, this
+                       -- object is not currently unlocked. But that could
+                       -- change while the transfer is in progress, so
+                       -- generate an inode cache for the starting
+                       -- content.
+                       then maybeToList <$>
+                               withTSDelta (liftIO . genInodeCache f)
+                       else pure cache
+               return $ if null cache'
+                       then Nothing
+                       else Just (f, sameInodeCache f cache')
        direct [] = return Nothing
        direct (f:fs) = do
                cache <- Direct.recordedInodeCache key
                -- check that we have a good file
-               ifM (Direct.sameInodeCache f cache)
-                       ( return $ Just (f, Direct.sameInodeCache f cache)
+               ifM (sameInodeCache f cache)
+                       ( return $ Just (f, sameInodeCache f cache)
                        , direct fs
                        )
 
index 890e40b5141ff25539617f9c72f2111c0597bdcd..6dc5345c9409633033449448a518812d62abc257 100644 (file)
@@ -672,7 +672,7 @@ wantHardLink :: Annex Bool
 wantHardLink = (annexHardLink <$> Annex.getGitConfig) <&&> (not <$> isDirect)
 
 -- Copies from src to dest, updating a meter. If the copy finishes
--- successfully, calls a final check action, which must also success, or
+-- successfully, calls a final check action, which must also succeed, or
 -- returns false.
 --
 -- If either the remote or local repository wants to use hard links,
index cc8da67d004a22f4b7a2e3adff2532d48f12886b..c203c95663e57fe879e3d75ea9e5e4a656a1639d 100644 (file)
@@ -328,8 +328,6 @@ files to be unlocked, while the indirect upgrades don't touch the files.
 * inAnnex check should fail in the case where an annexed object is unlocked
   and has had its content changed. Could use an InodeCache for
   such objects. This parallels how inAnnex checks work for direct mode.
-* Also, Annex.Content.prepSendAnnex should check the InodeCache for
-  changes.
 * Reconcile staged changes into the associated files database, whenever
   the database is queried.
 * See if the cases where the associated files database is not used can be