use separate lock from content file in v9

Windows has always used a separate lock file, but on unix, the content
file itself was locked, and in v9 that changes to also use a separate
lock file.

This needs to be tested more. Eg, what happens after dropping a file;
does the the content lock file get deleted too, or linger around?

Sponsored-by: Dartmouth College's Datalad project
This commit is contained in:
Joey Hess 2022-01-11 17:01:11 -04:00
parent 43f9d967ff
commit 3c042606c2
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
2 changed files with 25 additions and 14 deletions

View file

@ -115,8 +115,8 @@ lockContentShared key a = lockContentUsing lock key notpresent $
where
notpresent = giveup $ "failed to lock content: not present"
#ifndef mingw32_HOST_OS
lock contentfile Nothing = tryLockShared Nothing contentfile
lock _ (Just lockfile) = posixLocker tryLockShared lockfile
lock contentfile Nothing = tryLockShared Nothing contentfile
#else
lock = winLocker lockShared
#endif
@ -126,21 +126,25 @@ lockContentShared key a = lockContentUsing lock key notpresent $
-
- If locking fails, throws an exception rather than running the action.
-
- But, if locking fails because the the content is not present, runs the
- fallback action instead.
- If locking fails because the the content is not present, runs the
- fallback action instead. However, the content is not guaranteed to be
- present when this succeeds.
-}
lockContentForRemoval :: Key -> Annex a -> (ContentRemovalLock -> Annex a) -> Annex a
lockContentForRemoval key fallback a = lockContentUsing lock key fallback $
a (ContentRemovalLock key)
where
#ifndef mingw32_HOST_OS
{- Since content files are stored with the write bit disabled, have
- to fiddle with permissions to open for an exclusive lock. -}
lock contentfile Nothing = bracket_
(thawContent contentfile)
(freezeContent contentfile)
(tryLockExclusive Nothing contentfile)
lock _ (Just lockfile) = posixLocker tryLockExclusive lockfile
{- No lock file, so the content file itself is locked.
- Since content files are stored with the write bit
- disabled, have to fiddle with permissions to open
- for an exclusive lock. -}
lock contentfile Nothing =
bracket_
(thawContent contentfile)
(freezeContent contentfile)
(tryLockExclusive Nothing contentfile)
#else
lock = winLocker lockExclusive
#endif
@ -170,7 +174,7 @@ winLocker _ _ Nothing = return Nothing
{- The fallback action is run if the ContentLocker throws an IO exception
- and the content is not present. It's not guaranteed to always run when
- the content is not present, because the content file is not always
- the file that is locked eg on Windows a different file is locked. -}
- the file that is locked. -}
lockContentUsing :: ContentLocker -> Key -> Annex a -> Annex a -> Annex a
lockContentUsing locker key fallback a = do
contentfile <- calcRepo (gitAnnexLocation key)

View file

@ -24,6 +24,7 @@ import Annex.Content.Presence.LowLevel
import Annex.Common
import qualified Annex
import Annex.LockPool
import Annex.Version
import qualified Database.Keys
import Annex.InodeSentinal
import Utility.InodeCache
@ -115,13 +116,19 @@ inAnnexSafe key = inAnnex' (fromMaybe True) (Just False) go key
)
#endif
{- Windows has to use a separate lock file from the content, since
- locking the actual content file would interfere with the user's
- use of it. -}
contentLockFile :: Key -> Annex (Maybe RawFilePath)
#ifndef mingw32_HOST_OS
contentLockFile _ = pure Nothing
{- Older versions of git-annex locked content files themselves, but newer
- versions use a separate lock file, to better support repos shared
- amoung users in eg a group. -}
contentLockFile key = ifM (versionNeedsWritableContentFiles <$> getVersion)
( pure Nothing
, Just <$> calcRepo (gitAnnexContentLock key)
)
#else
{- Windows always has to use a separate lock file from the content, since
- locking the actual content file would interfere with the user's
- use of it. -}
contentLockFile key = Just <$> calcRepo (gitAnnexContentLock key)
#endif