summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2017-02-23 21:34:58 +0900
committerTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2017-02-23 21:34:58 +0900
commit8fc0c85125fc4d30decdedd4c1f454999397406a (patch)
tree6a922595e2bafe9f16a78efa9a9f6d2b7050c5b5
parent857d6a2a8e924618d37e75e6eda5e008a431cc48 (diff)
Propagate disk full error on pre-allocation to last error code
-rw-r--r--src/AbstractDiskWriter.cc37
-rw-r--r--src/FileAllocationCommand.cc1
2 files changed, 25 insertions, 13 deletions
diff --git a/src/AbstractDiskWriter.cc b/src/AbstractDiskWriter.cc
index ea4403fe..e8292224 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 1ac63e7b..335dec0b 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(),