narrow the race where a file gets modified before update-index
Check just before running update-index if the worktree file's content is still the same, don't update it when it's been modified. This narrows the race window a lot, from possibly minutes or hours, to seconds or less. (Use replaceFile so that the worktree update happens atomically, allowing the InodeCache of the new worktree file to itself be gathered w/o any other race.) This doesn't eliminate the race; it can still occur in the window before update-index runs. When annex.queue is large, a lot of files will be statted by the checks, and so the window may still be large enough to be a problem. When only a few files are being processed, the window is as small as it is in the race where a modification gets overwritten by git-annex when it updates the worktree. Or maybe as small as whatever race git checkout/pull/merge may have when the worktree gets modified during it. Still, I've kept a todo about this race. This commit was supported by the NSF-funded DataLad project.
This commit is contained in:
parent
6a445dc086
commit
82a239675f
5 changed files with 52 additions and 29 deletions
|
@ -26,7 +26,7 @@ import Utility.Path.Max
|
|||
-
|
||||
- Throws an IO exception when it was unable to replace the file.
|
||||
-}
|
||||
replaceFile :: FilePath -> (FilePath -> Annex ()) -> Annex ()
|
||||
replaceFile :: FilePath -> (FilePath -> Annex a) -> Annex a
|
||||
replaceFile file action = do
|
||||
misctmpdir <- fromRepo gitAnnexTmpMiscDir
|
||||
void $ createAnnexDirectory misctmpdir
|
||||
|
@ -43,8 +43,9 @@ replaceFile file action = do
|
|||
#endif
|
||||
withTmpDirIn misctmpdir basetmp $ \tmpdir -> do
|
||||
let tmpfile = tmpdir </> basetmp
|
||||
action tmpfile
|
||||
r <- action tmpfile
|
||||
liftIO $ replaceFileFrom tmpfile file
|
||||
return r
|
||||
|
||||
replaceFileFrom :: FilePath -> FilePath -> IO ()
|
||||
replaceFileFrom src dest = go `catchIO` fallback
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue