Clone
ixen <ixen@copyhandler.com>
committed
on 17 Nov 16
Fixed problem with IsFreshlyCreated causing task to go into error state when destination file is not accessible (CH-197)
ParallelizeReaderWriter + 3 more
/libchcore/TFilesystemFeedbackWrapper.cpp (+27 -27)
49 49                                 return TSubTaskBase::eSubResult_Continue;
50 50                         }
51 51                         catch (const TFileException& e)
52 52                         {
53 53                                 dwLastError = e.GetNativeError();
54 54                         }
55 55
56 56                         if (dwLastError == ERROR_ALREADY_EXISTS)
57 57                                 return TSubTaskBase::eSubResult_Continue;
58 58
59 59                         // log
60 60                         TString strFormat;
61 61                         strFormat = _T("Error %errno while calling CreateDirectory %path (ProcessFiles)");
62 62                         strFormat.Replace(_T("%errno"), boost::lexical_cast<std::wstring>(dwLastError).c_str());
63 63                         strFormat.Replace(_T("%path"), pathDirectory.ToString());
64 64                         LOG_ERROR(m_spLog) << strFormat.c_str();
65 65
66 66                         TFeedbackResult frResult = m_spFeedbackHandler->FileError(pathDirectory.ToWString(), TString(), EFileError::eCreateError, dwLastError);
67 67                         switch (frResult.GetResult())
68 68                         {
69                           case EFeedbackResult::eResult_Cancel:
  69                         case eResult_Cancel:
70 70                                 return TSubTaskBase::eSubResult_CancelRequest;
71 71
72                           case EFeedbackResult::eResult_Retry:
  72                         case eResult_Retry:
73 73                                 bRetry = true;
74 74                                 break;
75 75
76                           case EFeedbackResult::eResult_Pause:
  76                         case eResult_Pause:
77 77                                 return TSubTaskBase::eSubResult_PauseRequest;
78 78
79                           case EFeedbackResult::eResult_Skip:
  79                         case eResult_Skip:
80 80                                 return TSubTaskBase::eSubResult_Continue;
81 81
82 82                         default:
83 83                                 BOOST_ASSERT(FALSE);            // unknown result
84 84                                 throw TCoreException(eErr_UnhandledCase, L"Feedback result unknown", LOCATION);
85 85                         }
86 86
87 87                         if(WasKillRequested(frResult))
88 88                                 return TSubTaskBase::eSubResult_KillRequest;
89 89                 }
90 90                 while (bRetry);
91 91
92 92                 return TSubTaskBase::eSubResult_Continue;
93 93         }
94 94
95 95         bool TFilesystemFeedbackWrapper::WasKillRequested(const TFeedbackResult& rFeedbackResult) const
96 96         {
97 97                 if(m_rThreadController.KillRequested(rFeedbackResult.IsAutomatedReply() ? m_spFeedbackHandler->GetRetryInterval() : 0))
98 98                         return true;
99 99                 return false;
 
118 118                         {
119 119                                 m_spFilesystem->GetDynamicFreeSpace(pathDestination, ullAvailableSize, ullTotal);
120 120                         }
121 121                         catch (const TFileException& e)
122 122                         {
123 123                                 dwLastError = e.GetNativeError();
124 124                                 bCheckFailed = true;
125 125                         }
126 126
127 127                         if (bCheckFailed)
128 128                         {
129 129                                 TString strFormat;
130 130                                 strFormat = _T("Error %errno while checking free space at %path");
131 131                                 strFormat.Replace(_T("%errno"), boost::lexical_cast<std::wstring>(dwLastError).c_str());
132 132                                 strFormat.Replace(_T("%path"), pathDestination.ToString());
133 133                                 LOG_ERROR(m_spLog) << strFormat.c_str();
134 134
135 135                                 frResult = m_spFeedbackHandler->FileError(pathDestination.ToWString(), TString(), EFileError::eCheckForFreeSpace, dwLastError);
136 136                                 switch (frResult.GetResult())
137 137                                 {
138                                   case EFeedbackResult::eResult_Cancel:
  138                                 case eResult_Cancel:
139 139                                         return TSubTaskBase::eSubResult_CancelRequest;
140 140
141                                   case EFeedbackResult::eResult_Retry:
  141                                 case eResult_Retry:
142 142                                         bRetry = true;
143 143                                         break;
144 144
145                                   case EFeedbackResult::eResult_Pause:
  145                                 case eResult_Pause:
146 146                                         return TSubTaskBase::eSubResult_PauseRequest;
147 147
148                                   case EFeedbackResult::eResult_Skip:
  148                                 case eResult_Skip:
149 149                                         return TSubTaskBase::eSubResult_Continue;
150 150
151 151                                 default:
152 152                                         BOOST_ASSERT(FALSE);            // unknown result
153 153                                         throw TCoreException(eErr_UnhandledCase, L"Feedback result unknown", LOCATION);
154 154                                 }
155 155                         }
156 156
157 157                         if (!bRetry && ullNeededSize > ullAvailableSize)
158 158                         {
159 159                                 TString strFormat = _T("Not enough free space on disk - needed %needsize bytes for data, available: %availablesize bytes.");
160 160                                 strFormat.Replace(_T("%needsize"), boost::lexical_cast<std::wstring>(ullNeededSize).c_str());
161 161                                 strFormat.Replace(_T("%availablesize"), boost::lexical_cast<std::wstring>(ullAvailableSize).c_str());
162 162                                 LOG_WARNING(m_spLog) << strFormat.c_str();
163 163
164 164                                 frResult = m_spFeedbackHandler->NotEnoughSpace(pathFirstSrc.ToWString(), pathDestination.ToWString(), ullNeededSize);
165 165                                 switch (frResult.GetResult())
166 166                                 {
167                                   case EFeedbackResult::eResult_Cancel:
  167                                 case eResult_Cancel:
168 168                                         LOG_INFO(m_spLog) << _T("Cancel request while checking for free space on disk.");
169 169                                         return TSubTaskBase::eSubResult_CancelRequest;
170 170
171                                   case EFeedbackResult::eResult_Retry:
  171                                 case eResult_Retry:
172 172                                         LOG_INFO(m_spLog) << _T("Retrying to read drive's free space...");
173 173                                         bRetry = true;
174 174                                         break;
175 175
176                                   case EFeedbackResult::eResult_Ignore:
  176                                 case eResult_Ignore:
177 177                                         LOG_INFO(m_spLog) << _T("Ignored warning about not enough place on disk to copy data.");
178 178                                         return TSubTaskBase::eSubResult_Continue;
179 179
180 180                                 default:
181 181                                         BOOST_ASSERT(FALSE);            // unknown result
182 182                                         throw TCoreException(eErr_UnhandledCase, L"Feedback result unknown", LOCATION);
183 183                                 }
184 184                         }
185 185
186 186                         if(bRetry && WasKillRequested(frResult))
187 187                                 return TSubTaskBase::eSubResult_KillRequest;
188 188                 }
189 189                 while (bRetry);
190 190
191 191                 return TSubTaskBase::eSubResult_Continue;
192 192         }
193 193
194 194         TSubTaskBase::ESubOperationResult TFilesystemFeedbackWrapper::RemoveDirectoryFB(const TFileInfoPtr& spFileInfo, bool bProtectReadOnlyFiles)
195 195         {
196 196                 bool bRetry = false;
 
208 208                                 m_spFilesystem->RemoveDirectory(spFileInfo->GetFullFilePath());
209 209                                 return TSubTaskBase::eSubResult_Continue;
210 210                         }
211 211                         catch (const TFileException& e)
212 212                         {
213 213                                 dwLastError = e.GetNativeError();
214 214                         }
215 215
216 216                         if(dwLastError == ERROR_PATH_NOT_FOUND || dwLastError == ERROR_FILE_NOT_FOUND)
217 217                                 return TSubTaskBase::eSubResult_Continue;
218 218
219 219                         // log
220 220                         TString strFormat = _T("Error #%errno while deleting folder %path");
221 221                         strFormat.Replace(_T("%errno"), boost::lexical_cast<std::wstring>(dwLastError).c_str());
222 222                         strFormat.Replace(_T("%path"), spFileInfo->GetFullFilePath().ToString());
223 223                         LOG_ERROR(m_spLog) << strFormat.c_str();
224 224
225 225                         TFeedbackResult frResult = m_spFeedbackHandler->FileError(spFileInfo->GetFullFilePath().ToWString(), TString(), EFileError::eDeleteError, dwLastError);
226 226                         switch (frResult.GetResult())
227 227                         {
228                           case EFeedbackResult::eResult_Cancel:
  228                         case eResult_Cancel:
229 229                                 LOG_INFO(m_spLog) << _T("Cancel request while deleting file.");
230 230                                 return TSubTaskBase::eSubResult_CancelRequest;
231 231
232                           case EFeedbackResult::eResult_Retry:
  232                         case eResult_Retry:
233 233                                 bRetry = true;
234 234                                 break;  // no fcIndex bump, since we are trying again
235 235
236                           case EFeedbackResult::eResult_Pause:
  236                         case eResult_Pause:
237 237                                 return TSubTaskBase::eSubResult_PauseRequest;
238 238
239                           case EFeedbackResult::eResult_Skip:
  239                         case eResult_Skip:
240 240                                 return TSubTaskBase::eSubResult_Continue;               // just do nothing
241 241
242 242                         default:
243 243                                 BOOST_ASSERT(FALSE);            // unknown result
244 244                                 throw TCoreException(eErr_UnhandledCase, L"Feedback result unknown", LOCATION);
245 245                         }
246 246
247 247                         if(WasKillRequested(frResult))
248 248                                 return TSubTaskBase::eSubResult_KillRequest;
249 249                 }
250 250                 while (bRetry);
251 251
252 252                 return TSubTaskBase::eSubResult_Continue;
253 253         }
254 254
255 255         TSubTaskBase::ESubOperationResult TFilesystemFeedbackWrapper::DeleteFileFB(const TFileInfoPtr& spFileInfo, bool bProtectReadOnlyFiles)
256 256         {
257 257                 bool bRetry = false;
258 258                 do
259 259                 {
 
269 269                                 m_spFilesystem->DeleteFile(spFileInfo->GetFullFilePath());
270 270                                 return TSubTaskBase::eSubResult_Continue;
271 271                         }
272 272                         catch (const TFileException& e)
273 273                         {
274 274                                 dwLastError = e.GetNativeError();
275 275                         }
276 276
277 277                         if (dwLastError == ERROR_PATH_NOT_FOUND || dwLastError == ERROR_FILE_NOT_FOUND)
278 278                                 return TSubTaskBase::eSubResult_Continue;
279 279
280 280                         // log
281 281                         TString strFormat = _T("Error #%errno while deleting file %path");
282 282                         strFormat.Replace(_T("%errno"), boost::lexical_cast<std::wstring>(dwLastError).c_str());
283 283                         strFormat.Replace(_T("%path"), spFileInfo->GetFullFilePath().ToString());
284 284                         LOG_ERROR(m_spLog) << strFormat.c_str();
285 285
286 286                         TFeedbackResult frResult = m_spFeedbackHandler->FileError(spFileInfo->GetFullFilePath().ToWString(), TString(), EFileError::eDeleteError, dwLastError);
287 287                         switch (frResult.GetResult())
288 288                         {
289                           case EFeedbackResult::eResult_Cancel:
  289                         case eResult_Cancel:
290 290                                 LOG_INFO(m_spLog) << _T("Cancel request while deleting file.");
291 291                                 return TSubTaskBase::eSubResult_CancelRequest;
292 292
293                           case EFeedbackResult::eResult_Retry:
  293                         case eResult_Retry:
294 294                                 bRetry = true;
295 295                                 break;
296 296
297                           case EFeedbackResult::eResult_Pause:
  297                         case eResult_Pause:
298 298                                 return TSubTaskBase::eSubResult_PauseRequest;
299 299
300                           case EFeedbackResult::eResult_Skip:
  300                         case eResult_Skip:
301 301                                 return TSubTaskBase::eSubResult_Continue;               // just do nothing
302 302
303 303                         default:
304 304                                 BOOST_ASSERT(FALSE);            // unknown result
305 305                                 throw TCoreException(eErr_UnhandledCase, L"Feedback result unknown", LOCATION);
306 306                         }
307 307
308 308                         if(WasKillRequested(frResult))
309 309                                 return TSubTaskBase::eSubResult_KillRequest;
310 310                 }
311 311                 while(bRetry);
312 312
313 313                 return TSubTaskBase::eSubResult_Continue;
314 314         }
315 315
316 316         TSubTaskBase::ESubOperationResult TFilesystemFeedbackWrapper::FastMoveFB(const TFileInfoPtr& spFileInfo, const TSmartPath& pathDestination, const TBasePathDataPtr& spBasePath)
317 317         {
318 318                 bool bRetry = false;
319 319                 do
320 320                 {
 
333 333                         {
334 334                                 dwLastError = e.GetNativeError();
335 335                         }
336 336
337 337                         // check if this is one of the errors, that will just cause fast move to skip
338 338                         if (dwLastError == ERROR_ACCESS_DENIED || dwLastError == ERROR_ALREADY_EXISTS || dwLastError == ERROR_NOT_SAME_DEVICE)
339 339                         {
340 340                                 return TSubTaskBase::eSubResult_Continue;
341 341                         }
342 342
343 343                         //log
344 344                         TString strFormat = _T("Error %errno while calling fast move %srcpath -> %dstpath (TSubTaskFastMove)");
345 345                         strFormat.Replace(_T("%errno"), boost::lexical_cast<std::wstring>(dwLastError).c_str());
346 346                         strFormat.Replace(_T("%srcpath"), spFileInfo->GetFullFilePath().ToString());
347 347                         strFormat.Replace(_T("%dstpath"), pathDestination.ToString());
348 348                         LOG_ERROR(m_spLog) << strFormat.c_str();
349 349
350 350                         TFeedbackResult frResult = m_spFeedbackHandler->FileError(pathSrc.ToWString(), pathDestination.ToWString(), EFileError::eFastMoveError, dwLastError);
351 351                         switch (frResult.GetResult())
352 352                         {
353                           case EFeedbackResult::eResult_Cancel:
  353                         case eResult_Cancel:
354 354                                 return TSubTaskBase::eSubResult_CancelRequest;
355 355
356                           case EFeedbackResult::eResult_Retry:
  356                         case eResult_Retry:
357 357                                 bRetry = true;
358 358                                 break;
359 359
360                           case EFeedbackResult::eResult_Pause:
  360                         case eResult_Pause:
361 361                                 return TSubTaskBase::eSubResult_PauseRequest;
362 362
363                           case EFeedbackResult::eResult_Skip:
  363                         case eResult_Skip:
364 364                                 return TSubTaskBase::eSubResult_SkipFile;
365 365
366 366                         default:
367 367                                 BOOST_ASSERT(FALSE);            // unknown result
368 368                                 throw TCoreException(eErr_UnhandledCase, L"Feedback result unknown", LOCATION);
369 369                         }
370 370
371 371                         if(WasKillRequested(frResult))
372 372                                 return TSubTaskBase::eSubResult_KillRequest;
373 373                 }
374 374                 while (bRetry);
375 375
376 376                 return TSubTaskBase::eSubResult_Continue;
377 377         }
378 378
379 379         TSubTaskBase::ESubOperationResult TFilesystemFeedbackWrapper::GetFileInfoFB(const TSmartPath& pathCurrent, TFileInfoPtr& spFileInfo, const TBasePathDataPtr& spBasePath)
380 380         {
381 381                 bool bRetry = false;
382 382                 do
383 383                 {
384 384                         bRetry = false;
385 385
386 386                         // read attributes of src file/folder
387 387                         DWORD dwLastError = ERROR_SUCCESS;
388 388                         try
389 389                         {
390 390                                 m_spFilesystem->GetFileInfo(pathCurrent, spFileInfo, spBasePath);
391 391                                 return TSubTaskBase::eSubResult_Continue;
392 392                         }
393 393                         catch (const TFileException& e)
394 394                         {
395 395                                 dwLastError = e.GetNativeError();
396 396                         }
397 397
398 398                         TFeedbackResult frResult = m_spFeedbackHandler->FileError(pathCurrent.ToWString(), TString(), EFileError::eRetrieveFileInfo, dwLastError);
399 399                         switch (frResult.GetResult())
400 400                         {
401                           case EFeedbackResult::eResult_Cancel:
  401                         case eResult_Cancel:
402 402                                 return TSubTaskBase::eSubResult_CancelRequest;
403 403
404                           case EFeedbackResult::eResult_Retry:
  404                         case eResult_Retry:
405 405                                 bRetry = true;
406 406                                 break;
407 407
408                           case EFeedbackResult::eResult_Pause:
  408                         case eResult_Pause:
409 409                                 return TSubTaskBase::eSubResult_PauseRequest;
410 410
411                           case EFeedbackResult::eResult_Skip:
  411                         case eResult_Skip:
412 412                                 return TSubTaskBase::eSubResult_SkipFile;
413 413
414 414                         default:
415 415                                 BOOST_ASSERT(FALSE);            // unknown result
416 416                                 throw TCoreException(eErr_UnhandledCase, L"Feedback result unknown", LOCATION);
417 417                         }
418 418
419 419                         if(WasKillRequested(frResult))
420 420                                 return TSubTaskBase::eSubResult_KillRequest;
421 421                 }
422 422                 while(bRetry);
423 423
424 424                 return TSubTaskBase::eSubResult_Continue;
425 425         }
426 426 }