diff options
author | Joey Hess <joeyh@joeyh.name> | 2015-12-09 17:00:37 -0400 |
---|---|---|
committer | Joey Hess <joeyh@joeyh.name> | 2015-12-09 17:00:37 -0400 |
commit | 76ccac53916d308aa4806d38bb8cfb6a9d1f9081 (patch) | |
tree | 10f7618585df73c335c459f9562b04f37a7eb03f /Annex | |
parent | b5c8ba7db3ea2eb4f1cd28e49cadb5fd348ca738 (diff) |
add inode cache to the db
Renamed the db to keys, since it is various info about a Keys.
Dropping a key will update its pointer files, as long as their content can
be verified to be unmodified. This falls back to checksum verification, but
I want it to use an InodeCache of the key, for speed. But, I have not made
anything populate that cache yet.
Diffstat (limited to 'Annex')
-rw-r--r-- | Annex/Content.hs | 39 | ||||
-rw-r--r-- | Annex/Content/Direct.hs | 9 | ||||
-rw-r--r-- | Annex/InodeSentinal.hs | 9 |
3 files changed, 43 insertions, 14 deletions
diff --git a/Annex/Content.hs b/Annex/Content.hs index 564bc2dca..a530245b3 100644 --- a/Annex/Content.hs +++ b/Annex/Content.hs @@ -73,7 +73,8 @@ import qualified Backend import Types.NumCopies import Annex.UUID import Annex.InodeSentinal -import qualified Database.AssociatedFiles as AssociatedFiles +import Utility.InodeCache +import qualified Database.Keys {- Checks if a given key's content is currently present. -} inAnnex :: Key -> Annex Bool @@ -447,10 +448,10 @@ moveAnnex key src = withObjectLoc key storeobject storedirect ( alreadyhave , modifyContent dest $ do liftIO $ moveFile src dest - fs <- AssociatedFiles.getDb key + fs <- Database.Keys.getAssociatedFiles key if null fs then freezeContent dest - else mapM_ (populateAssociatedFile key dest) fs + else mapM_ (populatePointerFile key dest) fs ) storeindirect = storeobject =<< calcRepo (gitAnnexLocation key) @@ -480,8 +481,8 @@ moveAnnex key src = withObjectLoc key storeobject storedirect alreadyhave = liftIO $ removeFile src -populateAssociatedFile :: Key -> FilePath -> FilePath -> Annex () -populateAssociatedFile k obj f = go =<< isPointerFile f +populatePointerFile :: Key -> FilePath -> FilePath -> Annex () +populatePointerFile k obj f = go =<< isPointerFile f where go (Just k') | k == k' = liftIO $ do nukeFile f @@ -598,6 +599,8 @@ removeAnnex (ContentRemovalLock key) = withObjectLoc key remove removedirect secureErase file liftIO $ nukeFile file removeInodeCache key + mapM_ (void . tryIO . resetPointerFile key) + =<< Database.Keys.getAssociatedFiles key removedirect fs = do cache <- recordedInodeCache key removeInodeCache key @@ -607,6 +610,32 @@ removeAnnex (ContentRemovalLock key) = withObjectLoc key remove removedirect secureErase f replaceFile f $ makeAnnexLink l +{- To safely reset a pointer file, it has to be the unmodified content of + - the key. The expensive way to tell is to do a verification of its content. + - The cheaper way is to see if the InodeCache for the key matches the + - file. + -} +resetPointerFile :: Key -> FilePath -> Annex () +resetPointerFile key f = go =<< geti + where + go Nothing = noop + go (Just fc) = ifM (cheapcheck fc <||> expensivecheck fc) + ( do + secureErase f + liftIO $ nukeFile f + liftIO $ writeFile f (formatPointer key) + , noop + ) + cheapcheck fc = maybe (return False) (compareInodeCaches fc) + =<< Database.Keys.getInodeCache key + expensivecheck fc = ifM (verifyKeyContent AlwaysVerify Types.Remote.UnVerified key f) + -- The file could have been modified while it was + -- being verified. Detect that. + ( geti >>= maybe (return False) (compareInodeCaches fc) + , return False + ) + geti = withTSDelta (liftIO . genInodeCache f) + {- Runs the secure erase command if set, otherwise does nothing. - File may or may not be deleted at the end; caller is responsible for - making sure it's deleted. -} diff --git a/Annex/Content/Direct.hs b/Annex/Content/Direct.hs index 1edcbaed5..3d2ab1c58 100644 --- a/Annex/Content/Direct.hs +++ b/Annex/Content/Direct.hs @@ -180,15 +180,6 @@ sameFileStatus key f status = do ([], Nothing) -> return True _ -> return False -{- If the inodes have changed, only the size and mtime are compared. -} -compareInodeCaches :: InodeCache -> InodeCache -> Annex Bool -compareInodeCaches x y - | compareStrong x y = return True - | otherwise = ifM inodesChanged - ( return $ compareWeak x y - , return False - ) - elemInodeCaches :: InodeCache -> [InodeCache] -> Annex Bool elemInodeCaches _ [] = return False elemInodeCaches c (l:ls) = ifM (compareInodeCaches c l) diff --git a/Annex/InodeSentinal.hs b/Annex/InodeSentinal.hs index 7047a405c..450e3b967 100644 --- a/Annex/InodeSentinal.hs +++ b/Annex/InodeSentinal.hs @@ -14,6 +14,15 @@ import qualified Annex import Utility.InodeCache import Annex.Perms +{- If the inodes have changed, only the size and mtime are compared. -} +compareInodeCaches :: InodeCache -> InodeCache -> Annex Bool +compareInodeCaches x y + | compareStrong x y = return True + | otherwise = ifM inodesChanged + ( return $ compareWeak x y + , return False + ) + {- 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. |