From: Jason Dillaman Date: Thu, 28 Jul 2016 19:09:53 +0000 (-0400) Subject: librbd: request exclusive lock if current owner cannot execute op X-Git-Tag: v10.2.4~52^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=e6ac214f8a6d8773de032c83f5fdd7c65b68d53f;p=ceph.git librbd: request exclusive lock if current owner cannot execute op The initial krbd implementation will not support executing maintenance ops and instead will return -EOPNOTSUPP. In this case, librbd can take the lock and execute the operation. Fixes: http://tracker.ceph.com/issues/16171 Signed-off-by: Jason Dillaman (cherry picked from commit d2d2d90d64663905c2b81f7809f1d636db6b7fb1) --- diff --git a/src/librbd/Operations.cc b/src/librbd/Operations.cc index 6c9d9e72581a..6875f8b779c4 100644 --- a/src/librbd/Operations.cc +++ b/src/librbd/Operations.cc @@ -108,6 +108,7 @@ struct C_InvokeAsyncRequest : public Context { boost::function remote; std::set filter_error_codes; Context *on_finish; + bool request_lock = false; C_InvokeAsyncRequest(I &image_ctx, const std::string& request_type, bool permit_snapshot, @@ -191,7 +192,15 @@ struct C_InvokeAsyncRequest : public Context { C_InvokeAsyncRequest, &C_InvokeAsyncRequest::handle_acquire_exclusive_lock>( this); - image_ctx.exclusive_lock->try_lock(ctx); + + if (request_lock) { + // current lock owner doesn't support op -- try to perform + // the action locally + request_lock = false; + image_ctx.exclusive_lock->request_lock(ctx); + } else { + image_ctx.exclusive_lock->try_lock(ctx); + } owner_lock.put_read(); } @@ -233,7 +242,13 @@ struct C_InvokeAsyncRequest : public Context { CephContext *cct = image_ctx.cct; ldout(cct, 20) << __func__ << ": r=" << r << dendl; - if (r != -ETIMEDOUT && r != -ERESTART) { + if (r == -EOPNOTSUPP) { + ldout(cct, 5) << request_type << " not supported by current lock owner" + << dendl; + request_lock = true; + send_refresh_image(); + return; + } else if (r != -ETIMEDOUT && r != -ERESTART) { image_ctx.state->handle_update_notification(); complete(r);