diff --git a/iocore/aio/AIO.cc b/iocore/aio/AIO.cc index 52d45fe002d..62bfd4c04ac 100644 --- a/iocore/aio/AIO.cc +++ b/iocore/aio/AIO.cc @@ -58,8 +58,8 @@ int thread_is_created = 0; RecInt cache_config_threads_per_disk = 12; RecInt api_config_threads_per_disk = 12; -RecRawStatBlock *aio_rsb = nullptr; -Continuation *aio_err_callbck = nullptr; +RecRawStatBlock *aio_rsb = nullptr; +Continuation *aio_err_callback = nullptr; // AIO Stats std::atomic aio_num_read = 0; std::atomic aio_bytes_read = 0; @@ -153,9 +153,9 @@ new_AIOCallback() } void -ink_aio_set_callback(Continuation *callback) +ink_aio_set_err_callback(Continuation *callback) { - aio_err_callbck = callback; + aio_err_callback = callback; } void @@ -455,7 +455,7 @@ cache_op(AIOCallbackInternal *op) res += err; } op->aio_result = res; - ink_assert(op->aio_result == (int64_t)a->aio_nbytes); + ink_assert(op->ok()); } return 1; } diff --git a/iocore/aio/I_AIO.h b/iocore/aio/I_AIO.h index 47dc35c4449..0782640d6a3 100644 --- a/iocore/aio/I_AIO.h +++ b/iocore/aio/I_AIO.h @@ -77,7 +77,7 @@ struct AIOCallback : public Continuation { }; void ink_aio_init(ts::ModuleVersion version, AIOBackend backend = AIO_BACKEND_AUTO); -void ink_aio_set_callback(Continuation *error_callback); +void ink_aio_set_err_callback(Continuation *error_callback); int ink_aio_read(AIOCallback *op, int fromAPI = 0); // fromAPI is a boolean to indicate if this is from an API call such as upload proxy feature diff --git a/iocore/aio/P_AIO.h b/iocore/aio/P_AIO.h index a6ff603b7fa..c8c6eef6338 100644 --- a/iocore/aio/P_AIO.h +++ b/iocore/aio/P_AIO.h @@ -45,10 +45,10 @@ static constexpr ts::ModuleVersion AIO_MODULE_INTERNAL_VERSION{AIO_MODULE_PUBLIC TS_INLINE int AIOCallback::ok() { - return (off_t)aiocb.aio_nbytes == (off_t)aio_result; + return (aiocb.aio_nbytes == static_cast(aio_result)) && (aio_result >= 0); } -extern Continuation *aio_err_callbck; +extern Continuation *aio_err_callback; struct AIO_Reqs; @@ -92,13 +92,16 @@ AIOCallbackInternal::io_complete(int event, void *data) { (void)event; (void)data; - if (aio_err_callbck && !ok()) { + if (aio_err_callback && !ok()) { AIOCallback *err_op = new AIOCallbackInternal(); err_op->aiocb.aio_fildes = this->aiocb.aio_fildes; err_op->aiocb.aio_lio_opcode = this->aiocb.aio_lio_opcode; - err_op->mutex = aio_err_callbck->mutex; - err_op->action = aio_err_callbck; - eventProcessor.schedule_imm(err_op); + err_op->mutex = aio_err_callback->mutex; + err_op->action = aio_err_callback; + + // Take this lock in-line because we want to stop other I/O operations on this disk ASAP + SCOPED_MUTEX_LOCK(lock, aio_err_callback->mutex, this_ethread()); + err_op->action.continuation->handleEvent(EVENT_NONE, err_op); } if (!action.cancelled && action.continuation) { action.continuation->handleEvent(AIO_EVENT_DONE, this); diff --git a/iocore/cache/Cache.cc b/iocore/cache/Cache.cc index 0c7778ce327..0346012d76c 100644 --- a/iocore/cache/Cache.cc +++ b/iocore/cache/Cache.cc @@ -569,7 +569,7 @@ CacheProcessor::start_internal(int flags) memset(sds, 0, sizeof(Span *) * gndisks); gndisks = 0; - ink_aio_set_callback(new AIO_Callback_handler()); + ink_aio_set_err_callback(new AIO_failure_handler()); config_volumes.read_config_file(); @@ -1263,7 +1263,7 @@ Vol::handle_dir_clear(int event, void *data) if (event == AIO_EVENT_DONE) { op = static_cast(data); - if (static_cast(op->aio_result) != op->aiocb.aio_nbytes) { + if (!op->ok()) { Warning("unable to clear cache directory '%s'", hash_text.get()); disk->incrErrors(op); fd = -1; @@ -1292,7 +1292,7 @@ Vol::handle_dir_read(int event, void *data) AIOCallback *op = static_cast(data); if (event == AIO_EVENT_DONE) { - if (static_cast(op->aio_result) != op->aiocb.aio_nbytes) { + if (!op->ok()) { Note("Directory read failed: clearing cache directory %s", this->hash_text.get()); clear_dir(); return EVENT_DONE; @@ -1387,7 +1387,7 @@ Vol::handle_recover_from_data(int event, void * /* data ATS_UNUSED */) io.aiocb.aio_nbytes = (skip + len) - recover_pos; } } else if (event == AIO_EVENT_DONE) { - if (io.aiocb.aio_nbytes != static_cast(io.aio_result)) { + if (!io.ok()) { Warning("disk read error on recover '%s', clearing", hash_text.get()); disk->incrErrors(&io); goto Lclear; @@ -1647,7 +1647,7 @@ Vol::handle_header_read(int event, void *data) for (auto &i : hf) { ink_assert(op != nullptr); i = static_cast(op->aiocb.aio_buf); - if (static_cast(op->aio_result) != op->aiocb.aio_nbytes) { + if (!op->ok()) { Note("Header read failed: clearing cache directory %s", this->hash_text.get()); clear_dir(); return EVENT_DONE; @@ -1929,7 +1929,7 @@ CacheProcessor::has_online_storage() const } int -AIO_Callback_handler::handle_disk_failure(int /* event ATS_UNUSED */, void *data) +AIO_failure_handler::handle_disk_failure(int /* event ATS_UNUSED */, void *data) { /* search for the matching file descriptor */ if (!CacheProcessor::cache_ready) { @@ -2351,7 +2351,7 @@ CacheVC::removeEvent(int /* event ATS_UNUSED */, Event * /* e ATS_UNUSED */) goto Lcollision; } // check read completed correct FIXME: remove bad vols - if (static_cast(io.aio_result) != io.aiocb.aio_nbytes) { + if (!io.ok()) { goto Ldone; } { diff --git a/iocore/cache/CacheDir.cc b/iocore/cache/CacheDir.cc index b4bf725e4e8..adfe4467fd2 100644 --- a/iocore/cache/CacheDir.cc +++ b/iocore/cache/CacheDir.cc @@ -1103,7 +1103,7 @@ CacheSync::mainEvent(int event, Event *e) if (event == AIO_EVENT_DONE) { // AIO Thread - if (io.aio_result != static_cast(io.aiocb.aio_nbytes)) { + if (!io.ok()) { Warning("vol write error during directory sync '%s'", gvol[vol_idx]->hash_text.get()); event = EVENT_NONE; goto Ldone; diff --git a/iocore/cache/CacheDisk.cc b/iocore/cache/CacheDisk.cc index 35743acd0d9..4b7b66d1e97 100644 --- a/iocore/cache/CacheDisk.cc +++ b/iocore/cache/CacheDisk.cc @@ -147,7 +147,7 @@ CacheDisk::clearDone(int event, void * /* data ATS_UNUSED */) { ink_assert(event == AIO_EVENT_DONE); - if (io.aiocb.aio_nbytes != static_cast(io.aio_result)) { + if (!io.ok()) { Warning("Could not clear disk header for disk %s: declaring disk bad", path); incrErrors(&io); SET_DISK_BAD(this); @@ -163,7 +163,7 @@ CacheDisk::openStart(int event, void * /* data ATS_UNUSED */) { ink_assert(event == AIO_EVENT_DONE); - if (io.aiocb.aio_nbytes != static_cast(io.aio_result)) { + if (!io.ok()) { Warning("could not read disk header for disk %s: declaring disk bad", path); // the header could have random values by the AIO read error @@ -237,7 +237,7 @@ CacheDisk::syncDone(int event, void * /* data ATS_UNUSED */) { ink_assert(event == AIO_EVENT_DONE); - if (io.aiocb.aio_nbytes != static_cast(io.aio_result)) { + if (!io.ok()) { Warning("Error writing disk header for disk %s:disk bad", path); incrErrors(&io); SET_DISK_BAD(this); diff --git a/iocore/cache/CacheVol.cc b/iocore/cache/CacheVol.cc index 989c06a95f4..1613632868c 100644 --- a/iocore/cache/CacheVol.cc +++ b/iocore/cache/CacheVol.cc @@ -210,7 +210,7 @@ CacheVC::scanObject(int /* event ATS_UNUSED */, Event * /* e ATS_UNUSED */) goto Lread; } - if (static_cast(io.aio_result) != io.aiocb.aio_nbytes) { + if (!io.ok()) { result = (void *)-ECACHE_READ_FAIL; goto Ldone; } diff --git a/iocore/cache/P_CacheVol.h b/iocore/cache/P_CacheVol.h index 2800e899369..9c9e99592a6 100644 --- a/iocore/cache/P_CacheVol.h +++ b/iocore/cache/P_CacheVol.h @@ -256,10 +256,10 @@ struct Vol : public Continuation { ~Vol() override { ats_free(agg_buffer); } }; -struct AIO_Callback_handler : public Continuation { +struct AIO_failure_handler : public Continuation { int handle_disk_failure(int event, void *data); - AIO_Callback_handler() : Continuation(new_ProxyMutex()) { SET_HANDLER(&AIO_Callback_handler::handle_disk_failure); } + AIO_failure_handler() : Continuation(new_ProxyMutex()) { SET_HANDLER(&AIO_failure_handler::handle_disk_failure); } }; struct CacheVol {