From 02662f52920e84cd9464641ada84f6c3bbe3f86a Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Tue, 28 Mar 2023 15:21:10 -0400 Subject: [PATCH] fix concurrency bug causing EXPORT to be sent to the wrong external Fix bug that caused broken protocol to be used with external remotes that use exporttree=yes. In some cases this could result in the wrong content being exported to, or retrieved from the remote. Sponsored-by: Nicholas Golder-Manning on Patreon --- CHANGELOG | 3 +++ Remote/External.hs | 22 +++++++++++++++------- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index afa1699777..29f20cad5c 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -10,6 +10,9 @@ git-annex (10.20230322) UNRELEASED; urgency=medium * Windows: Support urls like "file:///c:/path" * addurl, importfeed: Fix failure when annex.securehashesonly is set. * Copy with a reflink when exporting a tree to a directory special remote. + * Fix bug that caused broken protocol to be used with external remotes + that use exporttree=yes. In some cases this could result in the wrong + content being exported to, or retrieved from the remote. -- Joey Hess Thu, 23 Mar 2023 15:04:41 -0400 diff --git a/Remote/External.hs b/Remote/External.hs index 4077030fa3..352b9eb68d 100644 --- a/Remote/External.hs +++ b/Remote/External.hs @@ -377,19 +377,27 @@ handleRequest external req mp responsehandler = handleRequest' st external req mp responsehandler handleRequestKey :: External -> (SafeKey -> Request) -> Key -> Maybe MeterUpdate -> ResponseHandler a -> Annex a -handleRequestKey external mkreq k mp responsehandler = case mkSafeKey k of - Right sk -> handleRequest external (mkreq sk) mp responsehandler +handleRequestKey external mkreq k mp responsehandler = + withSafeKey k $ \sk -> handleRequest external (mkreq sk) mp responsehandler + +withSafeKey :: Key -> (SafeKey -> Annex a) -> Annex a +withSafeKey k a = case mkSafeKey k of + Right sk -> a sk Left e -> giveup e {- Export location is first sent in an EXPORT message before - the main request. This is done because the ExportLocation can - contain spaces etc. -} handleRequestExport :: External -> ExportLocation -> (SafeKey -> Request) -> Key -> Maybe MeterUpdate -> ResponseHandler a -> Annex a -handleRequestExport external loc mkreq k mp responsehandler = do - withExternalState external $ \st -> do - checkPrepared st external - sendMessage st (EXPORT loc) - handleRequestKey external mkreq k mp responsehandler +handleRequestExport external loc mkreq k mp responsehandler = + withSafeKey k $ \sk -> + -- Both the EXPORT and subsequent request must be sent to the + -- same external process, so run both with the same external + -- state. + withExternalState external $ \st -> do + checkPrepared st external + sendMessage st (EXPORT loc) + handleRequest' st external (mkreq sk) mp responsehandler handleRequest' :: ExternalState -> External -> Request -> Maybe MeterUpdate -> ResponseHandler a -> Annex a handleRequest' st external req mp responsehandler -- 2.30.2