update chunk log after speculated chunks are verified to be present
Only done in checkPresentChunks, although retrieveChunks could also do it. Does not seem necessary though, because git-annex never retrives content without first checking if it's present AFAICR. And really this will only be needed when using fsck. Puttting it here, rather than in fsck avoids breaking an abstraction boundary, and is nice and inexpensive.
This commit is contained in:
parent
dad4be97c2
commit
b62e004c2c
2 changed files with 38 additions and 14 deletions
|
@ -206,7 +206,7 @@ seekResume h encryptor chunkkeys checker = do
|
||||||
-}
|
-}
|
||||||
removeChunks :: Remover -> UUID -> ChunkConfig -> EncKey -> Key -> Annex ()
|
removeChunks :: Remover -> UUID -> ChunkConfig -> EncKey -> Key -> Annex ()
|
||||||
removeChunks remover u chunkconfig encryptor k = do
|
removeChunks remover u chunkconfig encryptor k = do
|
||||||
ls <- chunkKeys u chunkconfig k
|
ls <- map chunkKeyList <$> chunkKeys u chunkconfig k
|
||||||
mapM_ (remover . encryptor) (concat ls)
|
mapM_ (remover . encryptor) (concat ls)
|
||||||
let chunksizes = catMaybes $ map (fromKey keyChunkSize <=< headMaybe) ls
|
let chunksizes = catMaybes $ map (fromKey keyChunkSize <=< headMaybe) ls
|
||||||
forM_ chunksizes $ chunksRemoved u k . FixedSizeChunks . fromIntegral
|
forM_ chunksizes $ chunksRemoved u k . FixedSizeChunks . fromIntegral
|
||||||
|
@ -245,7 +245,8 @@ retrieveChunks retriever u chunkconfig encryptor basek dest basep sink
|
||||||
(\e -> go (Just e) =<< chunkKeysOnly u chunkconfig basek)
|
(\e -> go (Just e) =<< chunkKeysOnly u chunkconfig basek)
|
||||||
| otherwise = go Nothing =<< chunkKeys u chunkconfig basek
|
| otherwise = go Nothing =<< chunkKeys u chunkconfig basek
|
||||||
where
|
where
|
||||||
go pe ls = do
|
go pe cks = do
|
||||||
|
let ls = map chunkKeyList cks
|
||||||
currsize <- liftIO $ catchMaybeIO $ getFileSize dest
|
currsize <- liftIO $ catchMaybeIO $ getFileSize dest
|
||||||
let ls' = maybe ls (setupResume ls) currsize
|
let ls' = maybe ls (setupResume ls) currsize
|
||||||
if any null ls'
|
if any null ls'
|
||||||
|
@ -359,14 +360,18 @@ checkPresentChunks checker u chunkconfig encryptor basek
|
||||||
where
|
where
|
||||||
checklists Nothing [] = return False
|
checklists Nothing [] = return False
|
||||||
checklists (Just deferrederror) [] = throwM deferrederror
|
checklists (Just deferrederror) [] = throwM deferrederror
|
||||||
checklists d (l:ls)
|
checklists d (ck:cks)
|
||||||
| not (null l) = do
|
| not (null l) = do
|
||||||
v <- checkchunks l
|
v <- checkchunks l
|
||||||
case v of
|
case v of
|
||||||
Left e -> checklists (Just e) ls
|
Left e -> checklists (Just e) cks
|
||||||
Right True -> return True
|
Right True -> do
|
||||||
Right False -> checklists Nothing ls
|
ensureChunksAreLogged u basek ck
|
||||||
| otherwise = checklists d ls
|
return True
|
||||||
|
Right False -> checklists Nothing cks
|
||||||
|
| otherwise = checklists d cks
|
||||||
|
where
|
||||||
|
l = chunkKeyList ck
|
||||||
|
|
||||||
checkchunks :: [Key] -> Annex (Either SomeException Bool)
|
checkchunks :: [Key] -> Annex (Either SomeException Bool)
|
||||||
checkchunks [] = return (Right True)
|
checkchunks [] = return (Right True)
|
||||||
|
@ -379,6 +384,14 @@ checkPresentChunks checker u chunkconfig encryptor basek
|
||||||
|
|
||||||
check = tryNonAsync . checker . encryptor
|
check = tryNonAsync . checker . encryptor
|
||||||
|
|
||||||
|
data ChunkKeys
|
||||||
|
= ChunkKeys [Key]
|
||||||
|
| SpeculativeChunkKeys (ChunkMethod, ChunkCount) [Key]
|
||||||
|
|
||||||
|
chunkKeyList :: ChunkKeys -> [Key]
|
||||||
|
chunkKeyList (ChunkKeys l) = l
|
||||||
|
chunkKeyList (SpeculativeChunkKeys _ l) = l
|
||||||
|
|
||||||
{- A key can be stored in a remote unchunked, or as a list of chunked keys.
|
{- A key can be stored in a remote unchunked, or as a list of chunked keys.
|
||||||
- This can be the case whether or not the remote is currently configured
|
- This can be the case whether or not the remote is currently configured
|
||||||
- to use chunking.
|
- to use chunking.
|
||||||
|
@ -395,22 +408,22 @@ checkPresentChunks checker u chunkconfig encryptor basek
|
||||||
- recover from data loss, where the chunk log didn't make it out,
|
- recover from data loss, where the chunk log didn't make it out,
|
||||||
- though only as long as the ChunkConfig is unchanged.
|
- though only as long as the ChunkConfig is unchanged.
|
||||||
-}
|
-}
|
||||||
chunkKeys :: UUID -> ChunkConfig -> Key -> Annex [[Key]]
|
chunkKeys :: UUID -> ChunkConfig -> Key -> Annex [ChunkKeys]
|
||||||
chunkKeys = chunkKeys' False
|
chunkKeys = chunkKeys' False
|
||||||
|
|
||||||
{- Same as chunkKeys, but excluding the unchunked key. -}
|
{- Same as chunkKeys, but excluding the unchunked key. -}
|
||||||
chunkKeysOnly :: UUID -> ChunkConfig -> Key -> Annex [[Key]]
|
chunkKeysOnly :: UUID -> ChunkConfig -> Key -> Annex [ChunkKeys]
|
||||||
chunkKeysOnly = chunkKeys' True
|
chunkKeysOnly = chunkKeys' True
|
||||||
|
|
||||||
chunkKeys' :: Bool -> UUID -> ChunkConfig -> Key -> Annex [[Key]]
|
chunkKeys' :: Bool -> UUID -> ChunkConfig -> Key -> Annex [ChunkKeys]
|
||||||
chunkKeys' onlychunks u chunkconfig k = do
|
chunkKeys' onlychunks u chunkconfig k = do
|
||||||
recorded <- getCurrentChunks u k
|
recorded <- getCurrentChunks u k
|
||||||
let recordedl = map (toChunkList k) recorded
|
let recordedl = map (ChunkKeys . toChunkList k) recorded
|
||||||
return $ addspeculative recorded $ if onlychunks
|
return $ addspeculative recorded $ if onlychunks
|
||||||
then recordedl
|
then recordedl
|
||||||
else if noChunks chunkconfig
|
else if noChunks chunkconfig
|
||||||
then [k] : recordedl
|
then ChunkKeys [k] : recordedl
|
||||||
else recordedl ++ [[k]]
|
else recordedl ++ [ChunkKeys [k]]
|
||||||
where
|
where
|
||||||
addspeculative recorded l = case chunkconfig of
|
addspeculative recorded l = case chunkconfig of
|
||||||
NoChunks -> l
|
NoChunks -> l
|
||||||
|
@ -422,10 +435,19 @@ chunkKeys' onlychunks u chunkconfig k = do
|
||||||
v = (FixedSizeChunks chunksz, chunkcount)
|
v = (FixedSizeChunks chunksz, chunkcount)
|
||||||
in if v `elem` recorded
|
in if v `elem` recorded
|
||||||
then l
|
then l
|
||||||
else l ++ [toChunkList k v]
|
else l ++ [SpeculativeChunkKeys v (toChunkList k v)]
|
||||||
LegacyChunks _ -> l
|
LegacyChunks _ -> l
|
||||||
|
|
||||||
toChunkList :: Key -> (ChunkMethod, ChunkCount) -> [Key]
|
toChunkList :: Key -> (ChunkMethod, ChunkCount) -> [Key]
|
||||||
toChunkList k (FixedSizeChunks chunksize, chunkcount) =
|
toChunkList k (FixedSizeChunks chunksize, chunkcount) =
|
||||||
takeChunkKeyStream chunkcount $ chunkKeyStream k chunksize
|
takeChunkKeyStream chunkcount $ chunkKeyStream k chunksize
|
||||||
toChunkList _ (UnknownChunks _, _) = []
|
toChunkList _ (UnknownChunks _, _) = []
|
||||||
|
|
||||||
|
{- When chunkKeys provided a speculative chunk list, and that has been
|
||||||
|
- verified to be present, use this to log it in the chunk log. This way,
|
||||||
|
- a later change to the chunk size of the remote won't prevent accessing
|
||||||
|
- the chunks. -}
|
||||||
|
ensureChunksAreLogged :: UUID -> Key -> ChunkKeys -> Annex ()
|
||||||
|
ensureChunksAreLogged u k (SpeculativeChunkKeys (chunkmethod, chunkcount) _) =
|
||||||
|
chunksStored u k chunkmethod chunkcount
|
||||||
|
ensureChunksAreLogged _ _ (ChunkKeys _) = return ()
|
||||||
|
|
|
@ -24,3 +24,5 @@ but `annex fsck --key KEY --from remote --fast`, since it doesn't have an exact
|
||||||
|
|
||||||
[[!meta author=yoh]]
|
[[!meta author=yoh]]
|
||||||
[[!tag projects/dandi]]
|
[[!tag projects/dandi]]
|
||||||
|
|
||||||
|
> [[done]] --[[Joey]]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue