]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: refresh image before executing maint op
authorJason Dillaman <dillaman@redhat.com>
Thu, 28 Apr 2016 15:46:20 +0000 (11:46 -0400)
committerJason Dillaman <dillaman@redhat.com>
Thu, 28 Apr 2016 17:00:04 +0000 (13:00 -0400)
If a maint op is interrupted and restarted, it's possible that the
image will need to be refreshed.

Signed-off-by: Jason Dillaman <dillaman@redhat.com>
src/librbd/Operations.cc
src/librbd/internal.cc

index 81219d4a745a2be257536789960645a56c44705b..3b15625ba788bcf6da079e35525fd7201fab287e 100644 (file)
@@ -79,6 +79,9 @@ struct C_InvokeAsyncRequest : public Context {
    *    . . . . . .   |   . . . . . . . . . . . . . . . . . .
    *    .         .   |   .                                 .
    *    .         v   v   v                                 .
+   *    .       REFRESH_IMAGE (skip if not needed)          .
+   *    .             |                                     .
+   *    .             v                                     .
    *    .       ACQUIRE_LOCK (skip if exclusive lock        .
    *    .             |       disabled or has lock)         .
    *    .             |                                     .
@@ -116,6 +119,35 @@ struct C_InvokeAsyncRequest : public Context {
   }
 
   void send() {
+    send_refresh_image();
+  }
+
+  void send_refresh_image() {
+    if (!image_ctx.state->is_refresh_required()) {
+      send_acquire_exclusive_lock();
+      return;
+    }
+
+    CephContext *cct = image_ctx.cct;
+    ldout(cct, 20) << __func__ << dendl;
+
+    Context *ctx = util::create_context_callback<
+      C_InvokeAsyncRequest<I>,
+      &C_InvokeAsyncRequest<I>::handle_refresh_image>(this);
+    image_ctx.state->refresh(ctx);
+  }
+
+  void handle_refresh_image(int r) {
+    CephContext *cct = image_ctx.cct;
+    ldout(cct, 20) << __func__ << ": r=" << r << dendl;
+
+    RWLock::RLocker owner_locker(image_ctx.owner_lock);
+    if (r < 0) {
+      lderr(cct) << "failed to refresh image: " << cpp_strerror(r) << dendl;
+      complete(r);
+      return;
+    }
+
     send_acquire_exclusive_lock();
   }
 
@@ -193,7 +225,7 @@ struct C_InvokeAsyncRequest : public Context {
 
     ldout(cct, 5) << request_type << " timed out notifying lock owner"
                   << dendl;
-    send_acquire_exclusive_lock();
+    send_refresh_image();
   }
 
   void send_local_request() {
@@ -213,7 +245,7 @@ struct C_InvokeAsyncRequest : public Context {
     ldout(cct, 20) << __func__ << ": r=" << r << dendl;
 
     if (r == -ERESTART) {
-      send_acquire_exclusive_lock();
+      send_refresh_image();
       return;
     }
     complete(r);
index 5276052c5190fd18f9031b27809082663c764625..3ac77935baffeb7b1a78923e7bc5f02cc10d0398 100644 (file)
@@ -1589,40 +1589,40 @@ remove_mirroring_image:
       return -EINVAL;
     }
 
-    {
-      RWLock::RLocker owner_locker(ictx->owner_lock);
-      RWLock::WLocker md_locker(ictx->md_lock);
-      r = ictx->flush();
-      if (r < 0) {
-        return r;
-      }
+    RWLock::RLocker owner_locker(ictx->owner_lock);
+    RWLock::WLocker md_locker(ictx->md_lock);
+    r = ictx->flush();
+    if (r < 0) {
+      return r;
+    }
 
-      uint64_t disable_mask = (RBD_FEATURES_MUTABLE |
-                               RBD_FEATURES_DISABLE_ONLY);
-      if ((enabled && (features & RBD_FEATURES_MUTABLE) != features) ||
-          (!enabled && (features & disable_mask) != features)) {
-        lderr(cct) << "cannot update immutable features" << dendl;
-        return -EINVAL;
-      } else if (features == 0) {
-        lderr(cct) << "update requires at least one feature" << dendl;
-        return -EINVAL;
-      }
+    uint64_t disable_mask = (RBD_FEATURES_MUTABLE |
+                             RBD_FEATURES_DISABLE_ONLY);
+    if ((enabled && (features & RBD_FEATURES_MUTABLE) != features) ||
+        (!enabled && (features & disable_mask) != features)) {
+      lderr(cct) << "cannot update immutable features" << dendl;
+      return -EINVAL;
+    } else if (features == 0) {
+      lderr(cct) << "update requires at least one feature" << dendl;
+      return -EINVAL;
+    }
 
-      // if disabling features w/ exclusive lock supported, we need to
-      // acquire the lock to temporarily block IO against the image
-      if (ictx->exclusive_lock != nullptr && !enabled) {
-        C_SaferCond lock_ctx;
-        ictx->exclusive_lock->request_lock(&lock_ctx);
-        r = lock_ctx.wait();
-        if (r < 0) {
-          lderr(cct) << "failed to lock image: " << cpp_strerror(r) << dendl;
-          return r;
-        } else if (!ictx->exclusive_lock->is_lock_owner()) {
-          lderr(cct) << "failed to acquire exclusive lock" << dendl;
-          return -EROFS;
-        }
+    // if disabling features w/ exclusive lock supported, we need to
+    // acquire the lock to temporarily block IO against the image
+    if (ictx->exclusive_lock != nullptr && !enabled) {
+      C_SaferCond lock_ctx;
+      ictx->exclusive_lock->request_lock(&lock_ctx);
+      r = lock_ctx.wait();
+      if (r < 0) {
+        lderr(cct) << "failed to lock image: " << cpp_strerror(r) << dendl;
+        return r;
+      } else if (!ictx->exclusive_lock->is_lock_owner()) {
+        lderr(cct) << "failed to acquire exclusive lock" << dendl;
+        return -EROFS;
       }
+    }
 
+    {
       RWLock::WLocker snap_locker(ictx->snap_lock);
       uint64_t new_features;
       if (enabled) {
@@ -1799,7 +1799,7 @@ remove_mirroring_image:
           img_ctx->state->close();
         }
       }
-   }
+    }
 
     ictx->notify_update();
     return 0;