From 168e588ac7af5ac3800e563884df097c6fa32f36 Mon Sep 17 00:00:00 2001 From: fly3366 <38378045+fly3366@users.noreply.github.com> Date: Mon, 4 Jan 2021 21:57:56 +0800 Subject: [PATCH] fix: Add reset offset (#1503) --- src/curl.cpp | 9 ++++++++- src/curl.h | 5 ++++- src/curl_multi.cpp | 29 +++++++++++++++++++++++++++-- 3 files changed, 39 insertions(+), 4 deletions(-) diff --git a/src/curl.cpp b/src/curl.cpp index b47d222..faaa7b1 100644 --- a/src/curl.cpp +++ b/src/curl.cpp @@ -723,6 +723,12 @@ bool S3fsCurl::SetDnsCache(bool isCache) return old; } +void S3fsCurl::ResetOffset(S3fsCurl* pCurl) +{ + pCurl->partdata.startpos = pCurl->b_partdata_startpos; + pCurl->partdata.size = pCurl->b_partdata_size; +} + bool S3fsCurl::SetSslSessionCache(bool isCache) { bool old = S3fsCurl::is_ssl_session_cache; @@ -1465,6 +1471,7 @@ S3fsCurl* S3fsCurl::ParallelGetObjectRetryCallback(S3fsCurl* s3fscurl) // duplicate request(setup new curl object) S3fsCurl* newcurl = new S3fsCurl(s3fscurl->IsUseAhbe()); + if(0 != (result = newcurl->PreGetObjectRequest(s3fscurl->path.c_str(), s3fscurl->partdata.fd, s3fscurl->partdata.startpos, s3fscurl->partdata.size, s3fscurl->b_ssetype, s3fscurl->b_ssevalue))){ S3FS_PRN_ERR("failed downloading part setup(%d)", result); delete newcurl; @@ -2244,7 +2251,7 @@ int S3fsCurl::RequestPerform(bool dontAddAuthHeaders /*=false*/) curl_easy_setopt(hCurl, CURLOPT_HTTPHEADER, requestHeaders); // Requests - CURLcode curlCode = curl_easy_perform(hCurl); + curlCode = curl_easy_perform(hCurl); // Check result switch(curlCode){ diff --git a/src/curl.h b/src/curl.h index 1efb402..54a5303 100644 --- a/src/curl.h +++ b/src/curl.h @@ -198,7 +198,8 @@ class S3fsCurl pthread_mutex_t *completed_tids_lock; std::vector *completed_tids; s3fscurl_lazy_setup fpLazySetup; // curl options for lazy setting function - + CURLcode curlCode; // handle curl return + public: static const long S3FSCURL_RESPONSECODE_NOTSET = -1; static const long S3FSCURL_RESPONSECODE_FATAL_ERROR = -2; @@ -333,6 +334,7 @@ class S3fsCurl } static long SetSslVerifyHostname(long value); static long GetSslVerifyHostname() { return S3fsCurl::ssl_verify_hostname; } + static void ResetOffset(S3fsCurl* pCurl); // maximum parallel GET and PUT requests static int SetMaxParallelCount(int value); static int GetMaxParallelCount() { return S3fsCurl::max_parallel_cnt; } @@ -398,6 +400,7 @@ class S3fsCurl headers_t* GetResponseHeaders() { return &responseHeaders; } BodyData* GetBodyData() { return &bodydata; } BodyData* GetHeadData() { return &headdata; } + CURLcode GetCurlCode() const { return curlCode; } long GetLastResponseCode() const { return LastResponseCode; } bool SetUseAhbe(bool ahbe); bool EnableUseAhbe() { return SetUseAhbe(true); } diff --git a/src/curl_multi.cpp b/src/curl_multi.cpp index fe6251a..a9f3fdd 100644 --- a/src/curl_multi.cpp +++ b/src/curl_multi.cpp @@ -186,8 +186,11 @@ int S3fsMultiCurl::MultiRead() bool isRetry = false; bool isPostpone = false; + bool isNeedResetOffset = true; long responseCode = S3fsCurl::S3FSCURL_RESPONSECODE_NOTSET; - if(s3fscurl->GetResponseCode(responseCode, false)){ + CURLcode curlCode = s3fscurl->GetCurlCode(); + + if(s3fscurl->GetResponseCode(responseCode, false) && curlCode == CURLE_OK){ if(S3fsCurl::S3FSCURL_RESPONSECODE_NOTSET == responseCode){ // This is a case where the processing result has not yet been updated (should be very rare). isPostpone = true; @@ -219,6 +222,23 @@ int S3fsMultiCurl::MultiRead() } }else{ S3FS_PRN_ERR("failed a request(Unknown response code: %s)", s3fscurl->url.c_str()); + // Reuse partical file + switch(curlCode){ + case CURLE_OPERATION_TIMEDOUT: + isRetry = true; + isNeedResetOffset = false; + break; + + case CURLE_PARTIAL_FILE: + isRetry = true; + isNeedResetOffset = false; + break; + + default: + S3FS_PRN_ERR("###curlCode: %d msg: %s", curlCode, curl_easy_strerror(curlCode)); + isRetry = true; + break; + } } if(isPostpone){ @@ -233,7 +253,12 @@ int S3fsMultiCurl::MultiRead() delete s3fscurl; }else{ S3fsCurl* retrycurl = NULL; - + + // Reset offset + if(isNeedResetOffset){ + S3fsCurl::ResetOffset(s3fscurl); + } + // For retry if(RetryCallback){ retrycurl = RetryCallback(s3fscurl);