diff options
-rw-r--r-- | Annex/Content.hs | 17 | ||||
-rw-r--r-- | doc/bugs/cyclic_drop.mdwn | 9 |
2 files changed, 19 insertions, 7 deletions
diff --git a/Annex/Content.hs b/Annex/Content.hs index 65dbe43f6..b111bfabc 100644 --- a/Annex/Content.hs +++ b/Annex/Content.hs @@ -65,8 +65,8 @@ inAnnexSafe = inAnnex' $ \f -> openForLock f False >>= check is_unlocked = Just True is_missing = Just False -{- Content is exclusively locked to indicate that it's in the process - - of being removed. (If the content is not present, no locking is done.) -} +{- Content is exclusively locked while running an action that might remove + - it. (If the content is not present, no locking is done.) -} lockContent :: Key -> Annex a -> Annex a lockContent key a = do file <- fromRepo $ gitAnnexLocation key @@ -85,11 +85,14 @@ openForLock file writelock = bracket_ prep cleanup $ (const $ return Nothing) where mode = if writelock then ReadWrite else ReadOnly - -- Since files are stored with the write bit disabled, - -- have to fiddle with permissions to open for an - -- exclusive lock. - prep = when writelock $ allowWrite file - cleanup = when writelock $ preventWrite file + {- Since files are stored with the write bit disabled, + - have to fiddle with permissions to open for an + - exclusive lock. flock locking would avoid this, + - but -} + prep = forwritelock $ allowWrite file + cleanup = forwritelock $ preventWrite file + forwritelock a = + when writelock $ whenM (doesFileExist file) $ a {- Calculates the relative path to use to link a file to a key. -} calcGitLink :: FilePath -> Key -> Annex FilePath diff --git a/doc/bugs/cyclic_drop.mdwn b/doc/bugs/cyclic_drop.mdwn index 7804380ae..beaaa6e35 100644 --- a/doc/bugs/cyclic_drop.mdwn +++ b/doc/bugs/cyclic_drop.mdwn @@ -73,6 +73,15 @@ Another cycle might be running move --to and move --from on the same file, locally. The exclusivity of the content lock solves this, as only one can run at a time. +Would it work with a shared lock? The --to would run git-annex-shell +inannex. The --from would also be running, and would run git-annex-shell +dropkey. So inannex and dropkey would end up running on the remote +at the same time. Dropkey takes the content lock, and inannex checks it, +but what if inannex runs first? Then it returns true, and then the content +is removed, so both the --to and --from see success and the --to proceeds +to remove the local content that the --from already caused to be removed +from the remote. So, no, the nasty exclusive lock is needed. + --- Another cycle might involve move --from and drop, both run on the same |