From 6caae86b7c7591b1e2902a9002b7649fe99022e5 Mon Sep 17 00:00:00 2001 From: xie xingguo Date: Fri, 15 Sep 2017 22:28:40 +0800 Subject: [PATCH] os/bluestore: propagate read-EIO for aio Signed-off-by: xie xingguo (cherry picked from commit 301912603789d78e3560da84df1e337edd046e46) --- src/os/bluestore/BlockDevice.h | 14 ++++++++++++-- src/os/bluestore/BlueStore.cc | 7 ++++++- src/os/bluestore/KernelDevice.cc | 32 +++++++++++++++++--------------- 3 files changed, 35 insertions(+), 18 deletions(-) diff --git a/src/os/bluestore/BlockDevice.h b/src/os/bluestore/BlockDevice.h index 5d511ddbb5708..280e650cb3653 100644 --- a/src/os/bluestore/BlockDevice.h +++ b/src/os/bluestore/BlockDevice.h @@ -32,6 +32,7 @@ struct IOContext { private: std::mutex lock; std::condition_variable cond; + int r = 0; public: CephContext* cct; @@ -46,9 +47,10 @@ public: std::list running_aios; ///< submitting or submitted std::atomic_int num_pending = {0}; std::atomic_int num_running = {0}; + bool allow_eio; - explicit IOContext(CephContext* cct, void *p) - : cct(cct), priv(p) + explicit IOContext(CephContext* cct, void *p, bool allow_eio = false) + : cct(cct), priv(p), allow_eio(allow_eio) {} // no copying @@ -76,6 +78,14 @@ public: --num_running; } } + + void set_return_value(int _r) { + r = _r; + } + + int get_return_value() const { + return r; + } }; diff --git a/src/os/bluestore/BlueStore.cc b/src/os/bluestore/BlueStore.cc index 2a414c1efc0d8..37ec919daba7a 100644 --- a/src/os/bluestore/BlueStore.cc +++ b/src/os/bluestore/BlueStore.cc @@ -6614,7 +6614,7 @@ int BlueStore::_do_read( // measure the whole block below. // The error isn't that much... vector compressed_blob_bls; - IOContext ioc(cct, NULL); + IOContext ioc(cct, NULL, true); // allow EIO for (auto& p : blobs2read) { BlobRef bptr = p.first; dout(20) << __func__ << " blob " << *bptr << std::hex @@ -6703,6 +6703,11 @@ int BlueStore::_do_read( bdev->aio_submit(&ioc); dout(20) << __func__ << " waiting for aio" << dendl; ioc.aio_wait(); + r = ioc.get_return_value(); + if (r < 0) { + assert(r == -EIO); // no other errors allowed + return -EIO; + } } logger->tinc(l_bluestore_read_wait_aio_lat, ceph_clock_now() - start); diff --git a/src/os/bluestore/KernelDevice.cc b/src/os/bluestore/KernelDevice.cc index 4dd2f9ca03e47..b3cc7795d9a92 100644 --- a/src/os/bluestore/KernelDevice.cc +++ b/src/os/bluestore/KernelDevice.cc @@ -371,21 +371,23 @@ void KernelDevice::_aio_thread() io_since_flush.store(true); int r = aio[i]->get_return_value(); - if (r < 0) { - derr << __func__ << " got " << cpp_strerror(r) << dendl; - assert(0 == "got unexpected error from io_getevents"); - } - - if (aio[i]->length != (uint64_t)r) { - derr << "aio to " << aio[i]->offset << "~" << aio[i]->length - << " but returned: " << r << dendl; - assert(0 == "unexpected aio error"); - } - - dout(10) << __func__ << " finished aio " << aio[i] << " r " << r - << " ioc " << ioc - << " with " << (ioc->num_running.load() - 1) - << " aios left" << dendl; + if (r < 0) { + derr << __func__ << " got " << cpp_strerror(r) << dendl; + if (ioc->allow_eio && r == -EIO) { + ioc->set_return_value(r); + } else { + assert(0 == "got unexpected error from io_getevents"); + } + } else if (aio[i]->length != (uint64_t)r) { + derr << "aio to " << aio[i]->offset << "~" << aio[i]->length + << " but returned: " << r << dendl; + assert(0 == "unexpected aio error"); + } + + dout(10) << __func__ << " finished aio " << aio[i] << " r " << r + << " ioc " << ioc + << " with " << (ioc->num_running.load() - 1) + << " aios left" << dendl; // NOTE: once num_running and we either call the callback or // call aio_wake we cannot touch ioc or aio[] as the caller -- 2.39.5