private:
std::mutex lock;
std::condition_variable cond;
+ int r = 0;
public:
CephContext* cct;
std::list<aio_t> 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
--num_running;
}
}
+
+ void set_return_value(int _r) {
+ r = _r;
+ }
+
+ int get_return_value() const {
+ return r;
+ }
};
// measure the whole block below.
// The error isn't that much...
vector<bufferlist> 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
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);
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