assistant: Fix a race condition that could cause a pointer file to get ingested into the annex

This was caused by commit fb8ab2469d putting
an isPointerFile check in the wrong place. So if the file was not a pointer
file at that point, but got replaced by one before the file got locked
down, the pointer file would be ingested into the annex.

The fix is simply to move the isPointerFile check to after safeToAdd locks
down the file. Now if the file changes to a pointer file after the
isPointerFile check, ingestion will see that it changed after lockdown,
and will refuse to add it to the annex.

Sponsored-by: the NIH-funded NICEMAN (ReproNim TR&D3) project
This commit is contained in:
Joey Hess 2024-07-02 12:24:57 -04:00
parent a65068fb66
commit 12a0ca9656
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
5 changed files with 45 additions and 8 deletions

View file

@ -290,19 +290,34 @@ handleAdds lockdowndir havelsof largefilematcher annexdotfiles delayadd cs = ret
refillChanges postponed
returnWhen (null toadd) $ do
(addedpointerfiles, toaddrest) <- partitionEithers
<$> mapM checkpointerfile toadd
(toaddannexed, toaddsmall) <- partitionEithers
<$> mapM checksmall toadd
<$> mapM checksmall toaddrest
addsmall toaddsmall
addedannexed <- addaction toadd $
catMaybes <$> addannexed toaddannexed
return $ addedannexed ++ toaddsmall ++ otherchanges
return $ addedannexed ++ toaddsmall ++ addedpointerfiles ++ otherchanges
where
(incomplete, otherchanges) = partition (\c -> isPendingAddChange c || isInProcessAddChange c) cs
returnWhen c a
| c = return otherchanges
| otherwise = a
checkpointerfile change = do
let file = toRawFilePath $ changeFile change
mk <- liftIO $ isPointerFile file
case mk of
Nothing -> return (Right change)
Just key -> do
mode <- liftIO $ catchMaybeIO $ fileMode <$> R.getFileStatus file
liftAnnex $ stagePointerFile file mode =<< hashPointerFile key
return $ Left $ Change
(changeTime change)
(changeFile change)
(LinkChange (Just key))
checksmall change
| not annexdotfiles && dotfile f =
return (Right change)

View file

@ -196,11 +196,8 @@ shouldRestage :: DaemonStatus -> Bool
shouldRestage ds = scanComplete ds || forceRestage ds
onAddFile :: Bool -> Handler
onAddFile symlinkssupported f fs = do
mk <- liftIO $ isPointerFile $ toRawFilePath f
case mk of
Nothing -> onAddFile' contentchanged addassociatedfile addlink samefilestatus symlinkssupported f fs
Just k -> addlink f k
onAddFile symlinkssupported f fs =
onAddFile' contentchanged addassociatedfile addlink samefilestatus symlinkssupported f fs
where
addassociatedfile key file =
Database.Keys.addAssociatedFile key