From 8fc0c85125fc4d30decdedd4c1f454999397406a Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Thu, 23 Feb 2017 21:34:58 +0900 Subject: [PATCH] Propagate disk full error on pre-allocation to last error code --- src/AbstractDiskWriter.cc | 37 +++++++++++++++++++++++------------- src/FileAllocationCommand.cc | 1 + 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/src/AbstractDiskWriter.cc b/src/AbstractDiskWriter.cc index ea4403fe10..e829222453 100644 --- a/src/AbstractDiskWriter.cc +++ b/src/AbstractDiskWriter.cc @@ -425,21 +425,29 @@ void AbstractDiskWriter::ensureMmapWrite(size_t len, int64_t offset) #endif // HAVE_MMAP || __MINGW32__ } +namespace { +// Returns true if |errNum| indicates that disk is full. +bool isDiskFullError(int errNum) +{ + return +#ifdef __MINGW32__ + errNum == ERROR_DISK_FULL || errNum == ERROR_HANDLE_DISK_FULL +#else // !__MINGW32__ + errNum == ENOSPC +#endif // !__MINGW32__ + ; +} +} // namespace + void AbstractDiskWriter::writeData(const unsigned char* data, size_t len, int64_t offset) { ensureMmapWrite(len, offset); if (writeDataInternal(data, len, offset) < 0) { int errNum = fileError(); - if ( -// If the error indicates disk full situation, throw -// DownloadFailureException and abort download instantly. -#ifdef __MINGW32__ - errNum == ERROR_DISK_FULL || errNum == ERROR_HANDLE_DISK_FULL -#else // !__MINGW32__ - errNum == ENOSPC -#endif // !__MINGW32__ - ) { + // If the error indicates disk full situation, throw + // DownloadFailureException and abort download instantly. + if (isDiskFullError(errNum)) { throw DOWNLOAD_FAILURE_EXCEPTION3( errNum, fmt(EX_FILE_WRITE, filename_.c_str(), fileStrerror(errNum).c_str()), @@ -546,16 +554,19 @@ void AbstractDiskWriter::allocate(int64_t offset, int64_t length, bool sparse) ; int errNum = errno; if (r == -1) { - throw DL_ABORT_EX3(errNum, fmt("fallocate failed. cause: %s", - util::safeStrerror(errNum).c_str()), - error_code::FILE_IO_ERROR); + throw DL_ABORT_EX3( + errNum, + fmt("fallocate failed. cause: %s", util::safeStrerror(errNum).c_str()), + isDiskFullError(errNum) ? error_code::NOT_ENOUGH_DISK_SPACE + : error_code::FILE_IO_ERROR); } #elif HAVE_POSIX_FALLOCATE int r = posix_fallocate(fd_, offset, length); if (r != 0) { throw DL_ABORT_EX3(r, fmt("posix_fallocate failed. cause: %s", util::safeStrerror(r).c_str()), - error_code::FILE_IO_ERROR); + isDiskFullError(r) ? error_code::NOT_ENOUGH_DISK_SPACE + : error_code::FILE_IO_ERROR); } #else #error "no *_fallocate function available." diff --git a/src/FileAllocationCommand.cc b/src/FileAllocationCommand.cc index 1ac63e7b44..335dec0bc7 100644 --- a/src/FileAllocationCommand.cc +++ b/src/FileAllocationCommand.cc @@ -92,6 +92,7 @@ bool FileAllocationCommand::executeInternal() bool FileAllocationCommand::handleException(Exception& e) { + getRequestGroup()->setLastErrorCode(e.getErrorCode(), e.what()); A2_LOG_ERROR_EX(fmt(MSG_FILE_ALLOCATION_FAILURE, getCuid()), e); A2_LOG_ERROR( fmt(MSG_DOWNLOAD_NOT_COMPLETE, getCuid(),