move InodeSentinal from direct mode code to its own module
Will be used outside of direct mode for v6 unlocked files, and is already used outside of direct mode when adding files to annex.
This commit is contained in:
parent
8a818088a3
commit
3311c48631
9 changed files with 93 additions and 61 deletions
|
@ -1,6 +1,6 @@
|
||||||
{- git-annex file content managing
|
{- git-annex file content managing
|
||||||
-
|
-
|
||||||
- Copyright 2010-2014 Joey Hess <id@joeyh.name>
|
- Copyright 2010-2015 Joey Hess <id@joeyh.name>
|
||||||
-
|
-
|
||||||
- Licensed under the GNU GPL version 3 or higher.
|
- Licensed under the GNU GPL version 3 or higher.
|
||||||
-}
|
-}
|
||||||
|
@ -72,6 +72,7 @@ import qualified Types.Backend
|
||||||
import qualified Backend
|
import qualified Backend
|
||||||
import Types.NumCopies
|
import Types.NumCopies
|
||||||
import Annex.UUID
|
import Annex.UUID
|
||||||
|
import Annex.InodeSentinal
|
||||||
import qualified Database.AssociatedFiles as AssociatedFiles
|
import qualified Database.AssociatedFiles as AssociatedFiles
|
||||||
|
|
||||||
{- Checks if a given key's content is currently present. -}
|
{- Checks if a given key's content is currently present. -}
|
||||||
|
@ -583,6 +584,9 @@ cleanObjectLoc key cleaner = do
|
||||||
<=< catchMaybeIO $ removeDirectory dir
|
<=< catchMaybeIO $ removeDirectory dir
|
||||||
|
|
||||||
{- Removes a key's file from .git/annex/objects/
|
{- Removes a key's file from .git/annex/objects/
|
||||||
|
-
|
||||||
|
- When a key has associated pointer files, they are checked for
|
||||||
|
- modifications, and if unmodified, are reset.
|
||||||
-
|
-
|
||||||
- In direct mode, deletes the associated files or files, and replaces
|
- In direct mode, deletes the associated files or files, and replaces
|
||||||
- them with symlinks.
|
- them with symlinks.
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
{- git-annex file content managing for direct mode
|
{- git-annex file content managing for direct mode
|
||||||
|
-
|
||||||
|
- This is deprecated, and will be removed when direct mode gets removed
|
||||||
|
- from git-annex.
|
||||||
-
|
-
|
||||||
- Copyright 2012-2014 Joey Hess <id@joeyh.name>
|
- Copyright 2012-2014 Joey Hess <id@joeyh.name>
|
||||||
-
|
-
|
||||||
- Licensed under the GNU GPL version 3 or higher.
|
- Licensed under the GNU GPL version 3 or higher.
|
||||||
-}
|
-}
|
||||||
|
|
||||||
{-# LANGUAGE CPP #-}
|
|
||||||
|
|
||||||
module Annex.Content.Direct (
|
module Annex.Content.Direct (
|
||||||
associatedFiles,
|
associatedFiles,
|
||||||
associatedFilesRelative,
|
associatedFilesRelative,
|
||||||
|
@ -26,15 +27,10 @@ module Annex.Content.Direct (
|
||||||
sameFileStatus,
|
sameFileStatus,
|
||||||
removeInodeCache,
|
removeInodeCache,
|
||||||
toInodeCache,
|
toInodeCache,
|
||||||
inodesChanged,
|
|
||||||
createInodeSentinalFile,
|
|
||||||
addContentWhenNotPresent,
|
addContentWhenNotPresent,
|
||||||
withTSDelta,
|
|
||||||
getTSDelta,
|
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Common.Annex
|
import Common.Annex
|
||||||
import qualified Annex
|
|
||||||
import Annex.Perms
|
import Annex.Perms
|
||||||
import qualified Git
|
import qualified Git
|
||||||
import Utility.Tmp
|
import Utility.Tmp
|
||||||
|
@ -43,6 +39,7 @@ import Utility.InodeCache
|
||||||
import Utility.CopyFile
|
import Utility.CopyFile
|
||||||
import Annex.ReplaceFile
|
import Annex.ReplaceFile
|
||||||
import Annex.Link
|
import Annex.Link
|
||||||
|
import Annex.InodeSentinal
|
||||||
|
|
||||||
{- Absolute FilePaths of Files in the tree that are associated with a key. -}
|
{- Absolute FilePaths of Files in the tree that are associated with a key. -}
|
||||||
associatedFiles :: Key -> Annex [FilePath]
|
associatedFiles :: Key -> Annex [FilePath]
|
||||||
|
@ -212,52 +209,3 @@ addContentWhenNotPresent key contentfile associatedfile = do
|
||||||
replaceFile associatedfile $
|
replaceFile associatedfile $
|
||||||
liftIO . void . copyFileExternal CopyAllMetaData contentfile
|
liftIO . void . copyFileExternal CopyAllMetaData contentfile
|
||||||
updateInodeCache key associatedfile
|
updateInodeCache key associatedfile
|
||||||
|
|
||||||
{- Some filesystems get new inodes each time they are mounted.
|
|
||||||
- In order to work on such a filesystem, a sentinal file is used to detect
|
|
||||||
- when the inodes have changed.
|
|
||||||
-
|
|
||||||
- If the sentinal file does not exist, we have to assume that the
|
|
||||||
- inodes have changed.
|
|
||||||
-}
|
|
||||||
inodesChanged :: Annex Bool
|
|
||||||
inodesChanged = sentinalInodesChanged <$> sentinalStatus
|
|
||||||
|
|
||||||
withTSDelta :: (TSDelta -> Annex a) -> Annex a
|
|
||||||
withTSDelta a = a =<< getTSDelta
|
|
||||||
|
|
||||||
getTSDelta :: Annex TSDelta
|
|
||||||
#ifdef mingw32_HOST_OS
|
|
||||||
getTSDelta = sentinalTSDelta <$> sentinalStatus
|
|
||||||
#else
|
|
||||||
getTSDelta = pure noTSDelta -- optimisation
|
|
||||||
#endif
|
|
||||||
|
|
||||||
sentinalStatus :: Annex SentinalStatus
|
|
||||||
sentinalStatus = maybe check return =<< Annex.getState Annex.sentinalstatus
|
|
||||||
where
|
|
||||||
check = do
|
|
||||||
sc <- liftIO . checkSentinalFile =<< annexSentinalFile
|
|
||||||
Annex.changeState $ \s -> s { Annex.sentinalstatus = Just sc }
|
|
||||||
return sc
|
|
||||||
|
|
||||||
{- The sentinal file is only created when first initializing a repository.
|
|
||||||
- If there are any annexed objects in the repository already, creating
|
|
||||||
- the file would invalidate their inode caches. -}
|
|
||||||
createInodeSentinalFile :: Annex ()
|
|
||||||
createInodeSentinalFile = unlessM (alreadyexists <||> hasobjects) $ do
|
|
||||||
s <- annexSentinalFile
|
|
||||||
createAnnexDirectory (parentDir (sentinalFile s))
|
|
||||||
liftIO $ writeSentinalFile s
|
|
||||||
where
|
|
||||||
alreadyexists = liftIO. sentinalFileExists =<< annexSentinalFile
|
|
||||||
hasobjects = liftIO . doesDirectoryExist =<< fromRepo gitAnnexObjectDir
|
|
||||||
|
|
||||||
annexSentinalFile :: Annex SentinalFile
|
|
||||||
annexSentinalFile = do
|
|
||||||
sentinalfile <- fromRepo gitAnnexInodeSentinal
|
|
||||||
sentinalcachefile <- fromRepo gitAnnexInodeSentinalCache
|
|
||||||
return SentinalFile
|
|
||||||
{ sentinalFile = sentinalfile
|
|
||||||
, sentinalCacheFile = sentinalcachefile
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
{- git-annex direct mode
|
{- git-annex direct mode
|
||||||
|
-
|
||||||
|
- This is deprecated, and will be removed when direct mode gets removed
|
||||||
|
- from git-annex.
|
||||||
-
|
-
|
||||||
- Copyright 2012-2014 Joey Hess <id@joeyh.name>
|
- Copyright 2012-2014 Joey Hess <id@joeyh.name>
|
||||||
-
|
-
|
||||||
|
@ -36,6 +39,7 @@ import Annex.VariantFile
|
||||||
import Git.Index
|
import Git.Index
|
||||||
import Annex.Index
|
import Annex.Index
|
||||||
import Annex.LockFile
|
import Annex.LockFile
|
||||||
|
import Annex.InodeSentinal
|
||||||
|
|
||||||
{- Uses git ls-files to find files that need to be committed, and stages
|
{- Uses git ls-files to find files that need to be committed, and stages
|
||||||
- them into the index. Returns True if some changes were staged. -}
|
- them into the index. Returns True if some changes were staged. -}
|
||||||
|
|
|
@ -32,9 +32,9 @@ import Annex.UUID
|
||||||
import Annex.Link
|
import Annex.Link
|
||||||
import Config
|
import Config
|
||||||
import Annex.Direct
|
import Annex.Direct
|
||||||
import Annex.Content.Direct
|
|
||||||
import Annex.Environment
|
import Annex.Environment
|
||||||
import Annex.Hook
|
import Annex.Hook
|
||||||
|
import Annex.InodeSentinal
|
||||||
import Upgrade
|
import Upgrade
|
||||||
#ifndef mingw32_HOST_OS
|
#ifndef mingw32_HOST_OS
|
||||||
import Utility.UserInfo
|
import Utility.UserInfo
|
||||||
|
@ -96,7 +96,7 @@ initialize' = do
|
||||||
, unlessM isBare
|
, unlessM isBare
|
||||||
switchHEADBack
|
switchHEADBack
|
||||||
)
|
)
|
||||||
createInodeSentinalFile
|
createInodeSentinalFile False
|
||||||
|
|
||||||
uninitialize :: Annex ()
|
uninitialize :: Annex ()
|
||||||
uninitialize = do
|
uninitialize = do
|
||||||
|
|
67
Annex/InodeSentinal.hs
Normal file
67
Annex/InodeSentinal.hs
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
{- git-annex inode sentinal file
|
||||||
|
-
|
||||||
|
- Copyright 2012-2015 Joey Hess <id@joeyh.name>
|
||||||
|
-
|
||||||
|
- Licensed under the GNU GPL version 3 or higher.
|
||||||
|
-}
|
||||||
|
|
||||||
|
{-# LANGUAGE CPP #-}
|
||||||
|
|
||||||
|
module Annex.InodeSentinal where
|
||||||
|
|
||||||
|
import Common.Annex
|
||||||
|
import qualified Annex
|
||||||
|
import Utility.InodeCache
|
||||||
|
import Annex.Perms
|
||||||
|
|
||||||
|
{- Some filesystems get new inodes each time they are mounted.
|
||||||
|
- In order to work on such a filesystem, a sentinal file is used to detect
|
||||||
|
- when the inodes have changed.
|
||||||
|
-
|
||||||
|
- If the sentinal file does not exist, we have to assume that the
|
||||||
|
- inodes have changed.
|
||||||
|
-}
|
||||||
|
inodesChanged :: Annex Bool
|
||||||
|
inodesChanged = sentinalInodesChanged <$> sentinalStatus
|
||||||
|
|
||||||
|
withTSDelta :: (TSDelta -> Annex a) -> Annex a
|
||||||
|
withTSDelta a = a =<< getTSDelta
|
||||||
|
|
||||||
|
getTSDelta :: Annex TSDelta
|
||||||
|
#ifdef mingw32_HOST_OS
|
||||||
|
getTSDelta = sentinalTSDelta <$> sentinalStatus
|
||||||
|
#else
|
||||||
|
getTSDelta = pure noTSDelta -- optimisation
|
||||||
|
#endif
|
||||||
|
|
||||||
|
sentinalStatus :: Annex SentinalStatus
|
||||||
|
sentinalStatus = maybe check return =<< Annex.getState Annex.sentinalstatus
|
||||||
|
where
|
||||||
|
check = do
|
||||||
|
sc <- liftIO . checkSentinalFile =<< annexSentinalFile
|
||||||
|
Annex.changeState $ \s -> s { Annex.sentinalstatus = Just sc }
|
||||||
|
return sc
|
||||||
|
|
||||||
|
{- The sentinal file is only created when first initializing a repository.
|
||||||
|
- If there are any annexed objects in the repository already, creating
|
||||||
|
- the file would invalidate their inode caches. -}
|
||||||
|
createInodeSentinalFile :: Bool -> Annex ()
|
||||||
|
createInodeSentinalFile evenwithobjects =
|
||||||
|
unlessM (alreadyexists <||> hasobjects) $ do
|
||||||
|
s <- annexSentinalFile
|
||||||
|
createAnnexDirectory (parentDir (sentinalFile s))
|
||||||
|
liftIO $ writeSentinalFile s
|
||||||
|
where
|
||||||
|
alreadyexists = liftIO. sentinalFileExists =<< annexSentinalFile
|
||||||
|
hasobjects
|
||||||
|
| evenwithobjects = pure False
|
||||||
|
| otherwise = liftIO . doesDirectoryExist =<< fromRepo gitAnnexObjectDir
|
||||||
|
|
||||||
|
annexSentinalFile :: Annex SentinalFile
|
||||||
|
annexSentinalFile = do
|
||||||
|
sentinalfile <- fromRepo gitAnnexInodeSentinal
|
||||||
|
sentinalcachefile <- fromRepo gitAnnexInodeSentinalCache
|
||||||
|
return SentinalFile
|
||||||
|
{ sentinalFile = sentinalfile
|
||||||
|
, sentinalCacheFile = sentinalcachefile
|
||||||
|
}
|
|
@ -30,6 +30,7 @@ import Config
|
||||||
import Annex.Content
|
import Annex.Content
|
||||||
import Annex.Link
|
import Annex.Link
|
||||||
import Annex.CatFile
|
import Annex.CatFile
|
||||||
|
import Annex.InodeSentinal
|
||||||
import qualified Annex
|
import qualified Annex
|
||||||
import Utility.InodeCache
|
import Utility.InodeCache
|
||||||
import Annex.Content.Direct
|
import Annex.Content.Direct
|
||||||
|
|
|
@ -32,6 +32,7 @@ import Annex.FileMatcher
|
||||||
import Annex.ReplaceFile
|
import Annex.ReplaceFile
|
||||||
import Utility.Tmp
|
import Utility.Tmp
|
||||||
import Utility.CopyFile
|
import Utility.CopyFile
|
||||||
|
import Annex.InodeSentinal
|
||||||
|
|
||||||
import Control.Exception (IOException)
|
import Control.Exception (IOException)
|
||||||
|
|
||||||
|
|
|
@ -9,10 +9,17 @@ module Upgrade.V5 where
|
||||||
|
|
||||||
import Common.Annex
|
import Common.Annex
|
||||||
import Config
|
import Config
|
||||||
|
import Annex.InodeSentinal
|
||||||
|
|
||||||
upgrade :: Bool -> Annex Bool
|
upgrade :: Bool -> Annex Bool
|
||||||
upgrade automatic = do
|
upgrade automatic = do
|
||||||
unless automatic $
|
unless automatic $
|
||||||
showAction "v5 to v6"
|
showAction "v5 to v6"
|
||||||
configureSmudgeFilter
|
configureSmudgeFilter
|
||||||
|
-- Inode sentinal file was only used in direct mode and when
|
||||||
|
-- locking down files as they were added. In v6, it's used more
|
||||||
|
-- extensively, so make sure it exists, since old repos that didn't
|
||||||
|
-- use direct mode may not have created it.
|
||||||
|
unlessM (isDirect) $
|
||||||
|
createInodeSentinalFile True
|
||||||
return True
|
return True
|
||||||
|
|
|
@ -325,12 +325,12 @@ files to be unlocked, while the indirect upgrades don't touch the files.
|
||||||
|
|
||||||
#### implementation todo list
|
#### implementation todo list
|
||||||
|
|
||||||
* inAnnex check should fail in the case where an annexed objects is unlocked
|
* inAnnex check should fail in the case where an annexed object is unlocked
|
||||||
and has had its content changed. Could use an InodeCache for
|
and has had its content changed. Could use an InodeCache for
|
||||||
such objects. This parallels how inAnnex checks work for direct mode.
|
such objects. This parallels how inAnnex checks work for direct mode.
|
||||||
* Reconcile staged changes into the associated files database, whenever
|
* Reconcile staged changes into the associated files database, whenever
|
||||||
the database is queried.
|
the database is queried.
|
||||||
* See if the case where the associated files database is not used can be
|
* See if the cases where the associated files database is not used can be
|
||||||
optimised. Eg, if the associated files database doesn't exist at all,
|
optimised. Eg, if the associated files database doesn't exist at all,
|
||||||
we know smudge/clean are not used, so queries for associated files don't
|
we know smudge/clean are not used, so queries for associated files don't
|
||||||
need to open the database or do reconciliation, but can simply return none.
|
need to open the database or do reconciliation, but can simply return none.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue