]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
librbd: flatten request now handles clone v2
authorJason Dillaman <dillaman@redhat.com>
Wed, 24 Jan 2018 21:26:51 +0000 (16:26 -0500)
committerJason Dillaman <dillaman@redhat.com>
Mon, 5 Feb 2018 16:12:00 +0000 (11:12 -0500)
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
src/librbd/operation/FlattenRequest.cc
src/librbd/operation/FlattenRequest.h

index 3ece4def307783a8c0e88da31960eb3a7d371e9b..4df4094ab9c071d0497f7bfb39bcd8ce64685b97 100644 (file)
@@ -5,6 +5,7 @@
 #include "librbd/AsyncObjectThrottle.h"
 #include "librbd/ExclusiveLock.h"
 #include "librbd/ImageCtx.h"
+#include "librbd/image/DetachChildRequest.h"
 #include "librbd/io/ObjectRequest.h"
 #include "common/dout.h"
 #include "common/errno.h"
@@ -75,10 +76,10 @@ bool FlattenRequest<I>::should_complete(int r) {
   switch (m_state) {
   case STATE_FLATTEN_OBJECTS:
     ldout(cct, 5) << "FLATTEN_OBJECTS" << dendl;
-    return send_update_children();
+    return send_detach_child();
 
-  case STATE_UPDATE_CHILDREN:
-    ldout(cct, 5) << "UPDATE_CHILDREN" << dendl;
+  case STATE_DETACH_CHILD:
+    ldout(cct, 5) << "DETACH_CHILD" << dendl;
     return send_update_header();
 
   case STATE_UPDATE_HEADER:
@@ -111,69 +112,66 @@ void FlattenRequest<I>::send_op() {
 }
 
 template <typename I>
-bool FlattenRequest<I>::send_update_header() {
+bool FlattenRequest<I>::send_detach_child() {
   I &image_ctx = this->m_image_ctx;
   assert(image_ctx.owner_lock.is_locked());
   CephContext *cct = image_ctx.cct;
 
-  ldout(cct, 5) << this << " send_update_header" << dendl;
-  m_state = STATE_UPDATE_HEADER;
-
   // should have been canceled prior to releasing lock
   assert(image_ctx.exclusive_lock == nullptr ||
          image_ctx.exclusive_lock->is_lock_owner());
 
+  // if there are no snaps, remove from the children object as well
+  // (if snapshots remain, they have their own parent info, and the child
+  // will be removed when the last snap goes away)
   {
-    RWLock::RLocker parent_locker(image_ctx.parent_lock);
-    // stop early if the parent went away - it just means
-    // another flatten finished first, so this one is useless.
-    if (!image_ctx.parent) {
-      ldout(cct, 5) << "image already flattened" << dendl;
-      return true;
+    RWLock::RLocker snap_locker(image_ctx.snap_lock);
+    if ((image_ctx.features & RBD_FEATURE_DEEP_FLATTEN) == 0 &&
+        !image_ctx.snaps.empty()) {
+      return send_update_header();
     }
-    m_parent_spec = image_ctx.parent_md.spec;
   }
 
-  // remove parent from this (base) image
-  librados::ObjectWriteOperation op;
-  cls_client::remove_parent(&op);
+  ldout(cct, 2) << "detaching child" << dendl;
+  m_state = STATE_DETACH_CHILD;
 
-  librados::AioCompletion *rados_completion = this->create_callback_completion();
-  int r = image_ctx.md_ctx.aio_operate(image_ctx.header_oid,
-                                        rados_completion, &op);
-  assert(r == 0);
-  rados_completion->release();
+  auto req = image::DetachChildRequest<I>::create(
+    image_ctx, this->create_callback_context());
+  req->send();
   return false;
 }
 
 template <typename I>
-bool FlattenRequest<I>::send_update_children() {
+bool FlattenRequest<I>::send_update_header() {
   I &image_ctx = this->m_image_ctx;
   assert(image_ctx.owner_lock.is_locked());
   CephContext *cct = image_ctx.cct;
 
+  ldout(cct, 5) << this << " send_update_header" << dendl;
+  m_state = STATE_UPDATE_HEADER;
+
   // should have been canceled prior to releasing lock
   assert(image_ctx.exclusive_lock == nullptr ||
          image_ctx.exclusive_lock->is_lock_owner());
 
-  // if there are no snaps, remove from the children object as well
-  // (if snapshots remain, they have their own parent info, and the child
-  // will be removed when the last snap goes away)
-  RWLock::RLocker snap_locker(image_ctx.snap_lock);
-  if ((image_ctx.features & RBD_FEATURE_DEEP_FLATTEN) == 0 &&
-      !image_ctx.snaps.empty()) {
-    return send_update_header();
+  {
+    RWLock::RLocker parent_locker(image_ctx.parent_lock);
+    // stop early if the parent went away - it just means
+    // another flatten finished first, so this one is useless.
+    if (!image_ctx.parent) {
+      ldout(cct, 5) << "image already flattened" << dendl;
+      return true;
+    }
+    m_parent_spec = image_ctx.parent_md.spec;
   }
 
-  ldout(cct, 2) << "removing child from children list..." << dendl;
-  m_state = STATE_UPDATE_CHILDREN;
-
+  // remove parent from this (base) image
   librados::ObjectWriteOperation op;
-  cls_client::remove_child(&op, m_parent_spec, image_ctx.id);
+  cls_client::remove_parent(&op);
 
   librados::AioCompletion *rados_completion = this->create_callback_completion();
-  int r = image_ctx.md_ctx.aio_operate(RBD_CHILDREN, rados_completion,
-                                    &op);
+  int r = image_ctx.md_ctx.aio_operate(image_ctx.header_oid,
+                                        rados_completion, &op);
   assert(r == 0);
   rados_completion->release();
   return false;
index 7d87c0ead08dd204f3841e204b346ffea3ab3015..54638700e5332b26cb568cdd5eea7efab2f4b784 100644 (file)
@@ -43,7 +43,7 @@ private:
    * <start>
    *    |
    *    v
-   * STATE_FLATTEN_OBJECTS ---> STATE_UPDATE_CHILDREN . . . .
+   * STATE_FLATTEN_OBJECTS ---> STATE_DETACH_CHILD  . . . . .
    *           .                         |                  .
    *           .                         |                  .
    *           .                         v                  .
@@ -57,13 +57,13 @@ private:
    *
    * @endverbatim
    *
-   * The _UPDATE_CHILDREN state will be skipped if the image has one or
+   * The _DETACH_CHILD state will be skipped if the image has one or
    * more snapshots. The _UPDATE_HEADER state will be skipped if the
    * image was concurrently flattened by another client.
    */
   enum State {
     STATE_FLATTEN_OBJECTS,
-    STATE_UPDATE_CHILDREN,
+    STATE_DETACH_CHILD,
     STATE_UPDATE_HEADER
   };
 
@@ -74,8 +74,8 @@ private:
 
   ParentSpec m_parent_spec;
 
+  bool send_detach_child();
   bool send_update_header();
-  bool send_update_children();
 };
 
 } // namespace operation