]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: request exclusive lock if current owner cannot execute op 10784/head
authorJason Dillaman <dillaman@redhat.com>
Thu, 28 Jul 2016 19:09:53 +0000 (15:09 -0400)
committerLoic Dachary <ldachary@redhat.com>
Fri, 19 Aug 2016 05:30:28 +0000 (07:30 +0200)
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 <dillaman@redhat.com>
(cherry picked from commit d2d2d90d64663905c2b81f7809f1d636db6b7fb1)

src/librbd/Operations.cc

index 6c9d9e72581a041d73dbfee97bf013d92a2f078c..6875f8b779c487f88732d867d94515e969c0f15d 100644 (file)
@@ -108,6 +108,7 @@ struct C_InvokeAsyncRequest : public Context {
   boost::function<void(Context*)> remote;
   std::set<int> 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<I>,
       &C_InvokeAsyncRequest<I>::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);