From a3b2d82c2410957f912b4742198c6e2bc2277fd6 Mon Sep 17 00:00:00 2001 From: Jason Dillaman Date: Wed, 24 Jan 2018 16:26:51 -0500 Subject: [PATCH] librbd: flatten request now handles clone v2 Signed-off-by: Jason Dillaman --- src/librbd/operation/FlattenRequest.cc | 70 +++++++++++++------------- src/librbd/operation/FlattenRequest.h | 8 +-- 2 files changed, 38 insertions(+), 40 deletions(-) diff --git a/src/librbd/operation/FlattenRequest.cc b/src/librbd/operation/FlattenRequest.cc index 3ece4def307..4df4094ab9c 100644 --- a/src/librbd/operation/FlattenRequest.cc +++ b/src/librbd/operation/FlattenRequest.cc @@ -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::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: @@ -110,6 +111,36 @@ void FlattenRequest::send_op() { throttle->start_ops(image_ctx.concurrent_management_ops); } +template +bool FlattenRequest::send_detach_child() { + I &image_ctx = this->m_image_ctx; + assert(image_ctx.owner_lock.is_locked()); + CephContext *cct = image_ctx.cct; + + // 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(); + } + } + + ldout(cct, 2) << "detaching child" << dendl; + m_state = STATE_DETACH_CHILD; + + auto req = image::DetachChildRequest::create( + image_ctx, this->create_callback_context()); + req->send(); + return false; +} + template bool FlattenRequest::send_update_header() { I &image_ctx = this->m_image_ctx; @@ -146,39 +177,6 @@ bool FlattenRequest::send_update_header() { return false; } -template -bool FlattenRequest::send_update_children() { - I &image_ctx = this->m_image_ctx; - assert(image_ctx.owner_lock.is_locked()); - CephContext *cct = image_ctx.cct; - - // 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(); - } - - ldout(cct, 2) << "removing child from children list..." << dendl; - m_state = STATE_UPDATE_CHILDREN; - - librados::ObjectWriteOperation op; - cls_client::remove_child(&op, m_parent_spec, image_ctx.id); - - librados::AioCompletion *rados_completion = this->create_callback_completion(); - int r = image_ctx.md_ctx.aio_operate(RBD_CHILDREN, rados_completion, - &op); - assert(r == 0); - rados_completion->release(); - return false; -} - } // namespace operation } // namespace librbd diff --git a/src/librbd/operation/FlattenRequest.h b/src/librbd/operation/FlattenRequest.h index 7d87c0ead08..54638700e53 100644 --- a/src/librbd/operation/FlattenRequest.h +++ b/src/librbd/operation/FlattenRequest.h @@ -43,7 +43,7 @@ private: * * | * 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