aboutsummaryrefslogtreecommitdiff
path: root/Annex/Content.hs
diff options
context:
space:
mode:
authorGravatar Joey Hess <joeyh@joeyh.name>2015-12-09 17:00:37 -0400
committerGravatar Joey Hess <joeyh@joeyh.name>2015-12-09 17:00:37 -0400
commit76ccac53916d308aa4806d38bb8cfb6a9d1f9081 (patch)
tree10f7618585df73c335c459f9562b04f37a7eb03f /Annex/Content.hs
parentb5c8ba7db3ea2eb4f1cd28e49cadb5fd348ca738 (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/Content.hs')
-rw-r--r--Annex/Content.hs39
1 files changed, 34 insertions, 5 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. -}