detect v10 upgrade while running

Capstone of the v10 upgrade process.

Tested with a git-annex drop in a v8 repo that had a local v8 remote.
Upgrading the repo to v10 (with --force) immedaitely caused it to notice
and switch over to v10 locking. Upgrading the remote also caused it to
switch over when operating on the remote.

The InodeCache makes this fairly efficient, just an added stat call per
lock of an object file. After the v10 upgrade, there is no more
overhead.

Sponsored-by: Dartmouth College's Datalad project
This commit is contained in:
Joey Hess 2022-01-21 12:56:07 -04:00
parent 2002d16dc3
commit dc14221bc3
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
2 changed files with 29 additions and 3 deletions

View file

@ -154,6 +154,7 @@ data AnnexState = AnnexState
, gitconfigadjustment :: (GitConfig -> GitConfig)
, gitconfigoverride :: [String]
, gitremotes :: Maybe [Git.Repo]
, gitconfiginodecache :: Maybe InodeCache
, backend :: Maybe (BackendA Annex)
, remotes :: [Types.Remote.RemoteA Annex]
, output :: MessageState
@ -214,6 +215,7 @@ newAnnexState c r = do
, gitconfigadjustment = id
, gitconfigoverride = []
, gitremotes = Nothing
, gitconfiginodecache = Nothing
, backend = Nothing
, remotes = []
, output = o

View file

@ -6,6 +6,7 @@
-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE OverloadedStrings #-}
module Annex.Content.Presence (
inAnnex,
@ -31,11 +32,15 @@ import qualified Database.Keys
import Annex.InodeSentinal
import Utility.InodeCache
import qualified Utility.RawFilePath as R
import qualified Git
import Config
#ifdef mingw32_HOST_OS
import Annex.Perms
#endif
import qualified System.FilePath.ByteString as P
{- Checks if a given key's content is currently present. -}
inAnnex :: Key -> Annex Bool
inAnnex key = inAnnexCheck key $ liftIO . R.doesPathExist
@ -130,10 +135,29 @@ inAnnexSafe key = inAnnex' (fromMaybe True) (Just False) go key
withContentLockFile :: Key -> (Maybe RawFilePath -> Annex a) -> Annex a
withContentLockFile k a = do
v <- getVersion
let go = contentLockFile k v >>= a
if versionNeedsWritableContentFiles v
then withSharedLock gitAnnexContentLockLock go
else go
then withSharedLock gitAnnexContentLockLock $ do
{- While the lock is held, check to see if the git
- config has changed, and reload it if so. This
- updates the annex.version after the v10 upgrade,
- so that a process that started in a v9 repository
- will switch over to v10 content lock files at the
- right time. -}
gitdir <- fromRepo Git.localGitDir
let gitconfig = gitdir P.</> "config"
ic <- withTSDelta (liftIO . genInodeCache gitconfig)
oldic <- Annex.getState Annex.gitconfiginodecache
v' <- if fromMaybe False (compareStrong <$> ic <*> oldic)
then pure v
else do
Annex.changeState $ \s ->
s { Annex.gitconfiginodecache = ic }
reloadConfig
getVersion
go (v')
else (go v)
where
go v = contentLockFile k v >>= a
contentLockFile :: Key -> Maybe RepoVersion -> Annex (Maybe RawFilePath)
#ifndef mingw32_HOST_OS