fixed the race breaking moving files from archive in direct mode

assistant: Fix bug in direct mode that could occur when a symlink is moved
out of an archive directory, and resulted in the file not being set to
direct mode when it was transferred.

The bug was that the direct mode mapping was not up-to-date when the
transferrer finished. So, finding no direct mode place to store the object,
it was put into .git/annex in indirect mode.

To fix this, just make the watcher update the direct mode mapping to
include the new file before it starts the transfer. (Seems we don't need to
update it to remove the old file if the link was moved, because the direct
mode code will notice it's not present and the mapping gets updated for its
removal later.)

The reason this was a race, and was probably not seen often is because
the committer came along and updated the direct mode mapping as part of
adding the moved symlink. But when the file was sufficiently small or
the remote sufficiently fast, this could happen after the transfer
finished.
This commit is contained in:
Joey Hess 2013-03-04 14:25:18 -04:00
parent 051622c6da
commit 1d388d5579
3 changed files with 11 additions and 4 deletions

View file

@ -19,6 +19,7 @@ import qualified Git.Config
import Utility.ThreadScheduler
import qualified Assistant.Threads.Watcher as Watcher
import Utility.LogFile
import Config
import Data.Time.Clock.POSIX
@ -105,7 +106,8 @@ dailyCheck = do
liftAnnex $ warning msg
void $ addAlert $ sanityCheckFixAlert msg
addsymlink file s = do
Watcher.runHandler Watcher.onAddSymlink file s
isdirect <- liftAnnex isDirect
Watcher.runHandler (Watcher.onAddSymlink isdirect) file s
insanity $ "found unstaged symlink: " ++ file
hourlyCheck :: Assistant ()

View file

@ -82,7 +82,7 @@ runWatcher = do
direct <- liftAnnex isDirect
addhook <- hook $ if direct then onAddDirect else onAdd
delhook <- hook onDel
addsymlinkhook <- hook onAddSymlink
addsymlinkhook <- hook $ onAddSymlink direct
deldirhook <- hook onDelDir
errhook <- hook onErr
let hooks = mkWatchHooks
@ -193,10 +193,12 @@ onAddDirect file fs = do
- Or, if it is a git-annex symlink, ensure it points to the content
- before adding it.
-}
onAddSymlink :: Handler
onAddSymlink file filestatus = go =<< liftAnnex (Backend.lookupFile file)
onAddSymlink :: Bool -> Handler
onAddSymlink isdirect file filestatus = go =<< liftAnnex (Backend.lookupFile file)
where
go (Just (key, _)) = do
when isdirect $
liftAnnex $ void $ addAssociatedFile key file
link <- liftAnnex $ calcGitLink file key
ifM ((==) (Just link) <$> liftIO (catchMaybeIO $ readSymbolicLink file))
( do

3
debian/changelog vendored
View file

@ -15,6 +15,9 @@ git-annex (4.20130228) UNRELEASED; urgency=low
very non-aggressively.
* webapp: New preferences page allows enabling/disabling debug logging
at runtime, as well as configuring numcopies and diskreserve.
* assistant: Fix bug in direct mode that could occur when a symlink is
moved out of an archive directory, and resulted in the file not being
set to direct mode when it was transferred.
-- Joey Hess <joeyh@debian.org> Wed, 27 Feb 2013 23:20:40 -0400