librbd: flatten request now handles clone v2

Signed-off-by: Jason Dillaman <dillaman@redhat.com>
This commit is contained in:
Jason Dillaman 2018-01-24 16:26:51 -05:00
parent 67ddd53488
commit a3b2d82c24
2 changed files with 38 additions and 40 deletions

View 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:
@ -110,6 +111,36 @@ void FlattenRequest<I>::send_op() {
throttle->start_ops(image_ctx.concurrent_management_ops);
}
template <typename I>
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;
// 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<I>::create(
image_ctx, this->create_callback_context());
req->send();
return false;
}
template <typename I>
bool FlattenRequest<I>::send_update_header() {
I &image_ctx = this->m_image_ctx;
@ -146,39 +177,6 @@ bool FlattenRequest<I>::send_update_header() {
return false;
}
template <typename I>
bool FlattenRequest<I>::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

View 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