From d2d2d90d64663905c2b81f7809f1d636db6b7fb1 Mon Sep 17 00:00:00 2001 From: Jason Dillaman Date: Thu, 28 Jul 2016 15:09:53 -0400 Subject: [PATCH] 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 --- src/librbd/Operations.cc | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/librbd/Operations.cc b/src/librbd/Operations.cc index e65db32e0fe9..bf904d26273b 100644 --- a/src/librbd/Operations.cc +++ b/src/librbd/Operations.cc @@ -111,6 +111,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, @@ -194,7 +195,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(); } @@ -236,7 +245,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); -- 2.47.3