From 9d4ae970bc3c95ad9a097f2b3c99dae58354800f Mon Sep 17 00:00:00 2001 From: Dhairya Parmar Date: Tue, 5 Dec 2023 17:10:56 +0530 Subject: [PATCH] client: handle callback completion if the async I/O failed and remove the context completion code from Client::_preadv_pwritev_locked since this case will indeed be handled in the Client::ll_preadv_pwritev along with all other cases Fixes: https://tracker.ceph.com/issues/63734 Signed-off-by: Dhairya Parmar --- src/client/Client.cc | 37 ++++++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/src/client/Client.cc b/src/client/Client.cc index 8682423ea1e1b..6ee5e742b9b2c 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -11259,11 +11259,6 @@ int64_t Client::_preadv_pwritev_locked(Fh *fh, const struct iovec *iov, onfinish); ldout(cct, 3) << "preadv(" << fh << ", " << offset << ") = " << r << dendl; if (r <= 0) { - if (r < 0 && onfinish != nullptr) { - client_lock.unlock(); - onfinish->complete(r); - client_lock.lock(); - } return r; } @@ -15960,9 +15955,37 @@ int64_t Client::ll_preadv_pwritev(struct Fh *fh, const struct iovec *iov, } std::scoped_lock cl(client_lock); - return _preadv_pwritev_locked(fh, iov, iovcnt, offset, write, true, - onfinish, bl, do_fsync, syncdataonly); + int64_t retval = _preadv_pwritev_locked(fh, iov, iovcnt, offset, write, + true, onfinish, bl, do_fsync, + syncdataonly); + /* There are two scenarios with each having two cases to handle here + 1) async io + 1.a) r == 0: + async call in progress, the context will be automatically invoked, + so just return the retval (i.e. zero). + 1.b) r < 0: + There was an error; no context completion should've took place so + complete the context with retval followed by returning zero to the + caller. + 2) sync io + 2.a) r >= 0: + sync call success; return the no. of bytes read/written. + 2.b) r < 0: + sync call failed; return the errno. */ + + if (retval < 0) { + if (onfinish != nullptr) { + //async io failed + client_lock.unlock(); + onfinish->complete(retval); + client_lock.lock(); + /* async call should always return zero to caller and allow the + caller to wait on callback for the actual errno/retval. */ + retval = 0; + } + } + return retval; } int Client::ll_flush(Fh *fh) -- 2.39.5