move InodeSentinal from direct mode code to its own module
authorJoey Hess <joeyh@joeyh.name>
Wed, 9 Dec 2015 19:42:16 +0000 (15:42 -0400)
committerJoey Hess <joeyh@joeyh.name>
Wed, 9 Dec 2015 19:52:11 +0000 (15:52 -0400)
Will be used outside of direct mode for v6 unlocked files, and is already
used outside of direct mode when adding files to annex.

Annex/Content.hs
Annex/Content/Direct.hs
Annex/Direct.hs
Annex/Init.hs
Annex/InodeSentinal.hs [new file with mode: 0644]
Assistant/Threads/Committer.hs
Command/Add.hs
Upgrade/V5.hs
doc/todo/smudge.mdwn

index d3bf4f94fe7a75655f35b867eb3e68dc69e194e8..564bc2dcae0f94529c41c9d83e94d09e8eadecdd 100644 (file)
@@ -1,6 +1,6 @@
 {- 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.
  -}
@@ -72,6 +72,7 @@ import qualified Types.Backend
 import qualified Backend
 import Types.NumCopies
 import Annex.UUID
+import Annex.InodeSentinal
 import qualified Database.AssociatedFiles as AssociatedFiles
 
 {- Checks if a given key's content is currently present. -}
@@ -583,6 +584,9 @@ cleanObjectLoc key cleaner = do
                        <=< catchMaybeIO $ removeDirectory dir
 
 {- 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
  - them with symlinks.
index 86e053d7f799ea2d747635ecfe85be08ed9ec3e5..1edcbaed51f289b920edb95cf3353dd12f5b8310 100644 (file)
@@ -1,12 +1,13 @@
 {- 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>
  -
  - Licensed under the GNU GPL version 3 or higher.
  -}
 
-{-# LANGUAGE CPP #-}
-
 module Annex.Content.Direct (
        associatedFiles,
        associatedFilesRelative,
@@ -26,15 +27,10 @@ module Annex.Content.Direct (
        sameFileStatus,
        removeInodeCache,
        toInodeCache,
-       inodesChanged,
-       createInodeSentinalFile,
        addContentWhenNotPresent,
-       withTSDelta,
-       getTSDelta,
 ) where
 
 import Common.Annex
-import qualified Annex
 import Annex.Perms
 import qualified Git
 import Utility.Tmp
@@ -43,6 +39,7 @@ import Utility.InodeCache
 import Utility.CopyFile
 import Annex.ReplaceFile
 import Annex.Link
+import Annex.InodeSentinal
 
 {- Absolute FilePaths of Files in the tree that are associated with a key. -}
 associatedFiles :: Key -> Annex [FilePath]
@@ -212,52 +209,3 @@ addContentWhenNotPresent key contentfile associatedfile = do
                replaceFile associatedfile $
                        liftIO . void . copyFileExternal CopyAllMetaData contentfile
        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
-               }
index 803f020cac1c2811ad28183ba8adb26802bc49ed..8fced2d4440b16c9e2ef0942bd1ba39b83bfe5fd 100644 (file)
@@ -1,4 +1,7 @@
 {- 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>
  -
@@ -36,6 +39,7 @@ import Annex.VariantFile
 import Git.Index
 import Annex.Index
 import Annex.LockFile
+import Annex.InodeSentinal
 
 {- 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. -}
index 7eea0dfa139172434ec8dc46be4912cb84671827..997312c31e50112d371faec55fed10d3107268eb 100644 (file)
@@ -32,9 +32,9 @@ import Annex.UUID
 import Annex.Link
 import Config
 import Annex.Direct
-import Annex.Content.Direct
 import Annex.Environment
 import Annex.Hook
+import Annex.InodeSentinal
 import Upgrade
 #ifndef mingw32_HOST_OS
 import Utility.UserInfo
@@ -96,7 +96,7 @@ initialize' = do
                , unlessM isBare
                        switchHEADBack
                )
-       createInodeSentinalFile
+       createInodeSentinalFile False
 
 uninitialize :: Annex ()
 uninitialize = do
diff --git a/Annex/InodeSentinal.hs b/Annex/InodeSentinal.hs
new file mode 100644 (file)
index 0000000..7047a40
--- /dev/null
@@ -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
+               }
index 59ca69e88e52e082a6963dede6db243c619d6c85..745047d9dcf195068b4b8d060f28fdd794d90c9f 100644 (file)
@@ -30,6 +30,7 @@ import Config
 import Annex.Content
 import Annex.Link
 import Annex.CatFile
+import Annex.InodeSentinal
 import qualified Annex
 import Utility.InodeCache
 import Annex.Content.Direct
index 27c11eab4350cd33aab3706366d0d8916ca65c87..f4bdc70c9808123f9caab77cc7052d60f0b73a84 100644 (file)
@@ -32,6 +32,7 @@ import Annex.FileMatcher
 import Annex.ReplaceFile
 import Utility.Tmp
 import Utility.CopyFile
+import Annex.InodeSentinal
 
 import Control.Exception (IOException)
 
index cf273bb16a9e788c341f17e3d7ca6b67d67ede82..e4501302dd942e4b72e100541e585362db7dcf4c 100644 (file)
@@ -9,10 +9,17 @@ module Upgrade.V5 where
 
 import Common.Annex
 import Config
+import Annex.InodeSentinal
 
 upgrade :: Bool -> Annex Bool
 upgrade automatic = do
        unless automatic $
                showAction "v5 to v6"
        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
index 373c655617268d21e2158df186937accef1dd340..60cc65f3fcfcca116c1e965438b92f2a520e5ef4 100644 (file)
@@ -325,12 +325,12 @@ files to be unlocked, while the indirect upgrades don't touch the files.
 
 #### 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
   such objects. This parallels how inAnnex checks work for direct mode.
 * Reconcile staged changes into the associated files database, whenever
   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,
   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.