summaryrefslogtreecommitdiff
path: root/Annex/Content.hs
diff options
context:
space:
mode:
authorGravatar Joey Hess <joeyh@joeyh.name>2015-12-09 17:47:05 -0400
committerGravatar Joey Hess <joeyh@joeyh.name>2015-12-09 17:54:54 -0400
commitd2d501503d9aa19787466129394141c794bb84e6 (patch)
tree3a0e3982e420ec42e2d90672628c4d63c7f78eff /Annex/Content.hs
parent76ccac53916d308aa4806d38bb8cfb6a9d1f9081 (diff)
use InodeCache when dropping a key to see if a pointer file can be safely reset
The Keys database can hold multiple inode caches for a given key. One for the annex object, and one for each pointer file, which may not be hard linked to it. Inode caches for a key are recorded when its content is added to the annex, but only if it has known pointer files. This is to avoid the overhead of maintaining the database when not needed. When the smudge filter outputs a file's content, the inode cache is not updated, because git's smudge interface doesn't let us write the file. So, dropping will fall back to doing an expensive verification then. Ideally, git's interface would be improved, and then the inode cache could be updated then too.
Diffstat (limited to 'Annex/Content.hs')
-rw-r--r--Annex/Content.hs22
1 files changed, 15 insertions, 7 deletions
diff --git a/Annex/Content.hs b/Annex/Content.hs
index a530245b3..e635b97a3 100644
--- a/Annex/Content.hs
+++ b/Annex/Content.hs
@@ -451,7 +451,9 @@ moveAnnex key src = withObjectLoc key storeobject storedirect
fs <- Database.Keys.getAssociatedFiles key
if null fs
then freezeContent dest
- else mapM_ (populatePointerFile key dest) fs
+ else do
+ mapM_ (populatePointerFile key dest) fs
+ Database.Keys.storeInodeCaches key (dest:fs)
)
storeindirect = storeobject =<< calcRepo (gitAnnexLocation key)
@@ -505,7 +507,9 @@ linkAnnex key src = do
( return LinkAnnexNoop
, modifyContent dest $
ifM (liftIO $ createLinkOrCopy src dest)
- ( return LinkAnnexOk
+ ( do
+ Database.Keys.storeInodeCaches key [dest, src]
+ return LinkAnnexOk
, return LinkAnnexFailed
)
)
@@ -601,6 +605,7 @@ removeAnnex (ContentRemovalLock key) = withObjectLoc key remove removedirect
removeInodeCache key
mapM_ (void . tryIO . resetPointerFile key)
=<< Database.Keys.getAssociatedFiles key
+ Database.Keys.removeInodeCaches key
removedirect fs = do
cache <- recordedInodeCache key
removeInodeCache key
@@ -613,8 +618,7 @@ removeAnnex (ContentRemovalLock key) = withObjectLoc key remove removedirect
{- 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.
- -}
+ - file. -}
resetPointerFile :: Key -> FilePath -> Annex ()
resetPointerFile key f = go =<< geti
where
@@ -624,10 +628,14 @@ resetPointerFile key f = go =<< geti
secureErase f
liftIO $ nukeFile f
liftIO $ writeFile f (formatPointer key)
- , noop
+ -- Can't delete the pointer file.
+ -- If it was a hard link to the annex object,
+ -- that object might have been frozen as part of the
+ -- removal process, so thaw it.
+ , thawContent f
)
- cheapcheck fc = maybe (return False) (compareInodeCaches fc)
- =<< Database.Keys.getInodeCache key
+ cheapcheck fc = anyM (compareInodeCaches fc)
+ =<< Database.Keys.getInodeCaches key
expensivecheck fc = ifM (verifyKeyContent AlwaysVerify Types.Remote.UnVerified key f)
-- The file could have been modified while it was
-- being verified. Detect that.