finish_op_ctx->complete(0);
});
auto req = image::AttachParentRequest<I>::create(
- *m_image_ctx, m_parent_spec, m_parent_overlap, ctx);
+ *m_image_ctx, m_parent_spec, m_parent_overlap, false, ctx);
req->send();
}
-// -*- mode:C++; tab-width:8; c-basic-offattach:2; indent-tabs-mode:t -*-
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab
#include "librbd/image/AttachParentRequest.h"
namespace librbd {
namespace image {
-using util::create_context_callback;
using util::create_rados_callback;
template <typename I>
librados::ObjectWriteOperation op;
if (!m_legacy_parent) {
librbd::cls_client::parent_attach(&op, m_parent_image_spec,
- m_parent_overlap);
+ m_parent_overlap, m_reattach);
} else {
librbd::cls_client::set_parent(&op, m_parent_image_spec, m_parent_overlap);
}
auto cct = m_image_ctx.cct;
ldout(cct, 5) << dendl;
- if (!m_legacy_parent && r == -EOPNOTSUPP) {
+ if (!m_legacy_parent && r == -EOPNOTSUPP && !m_reattach) {
if (m_parent_image_spec.pool_namespace ==
m_image_ctx.md_ctx.get_namespace()) {
m_parent_image_spec.pool_namespace = "";
-// -*- mode:C++; tab-width:8; c-basic-offattach:2; indent-tabs-mode:t -*-
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab
#ifndef CEPH_LIBRBD_IMAGE_ATTACH_PARENT_REQUEST_H
static AttachParentRequest* create(ImageCtxT& image_ctx,
const cls::rbd::ParentImageSpec& pspec,
uint64_t parent_overlap,
+ bool reattach,
Context* on_finish) {
- return new AttachParentRequest(image_ctx, pspec, parent_overlap, on_finish);
+ return new AttachParentRequest(image_ctx, pspec, parent_overlap, reattach,
+ on_finish);
}
AttachParentRequest(ImageCtxT& image_ctx,
const cls::rbd::ParentImageSpec& pspec,
- uint64_t parent_overlap, Context* on_finish)
+ uint64_t parent_overlap, bool reattach,
+ Context* on_finish)
: m_image_ctx(image_ctx), m_parent_image_spec(pspec),
- m_parent_overlap(parent_overlap), m_on_finish(on_finish) {
+ m_parent_overlap(parent_overlap), m_reattach(reattach),
+ m_on_finish(on_finish) {
}
void send();
ImageCtxT& m_image_ctx;
cls::rbd::ParentImageSpec m_parent_image_spec;
uint64_t m_parent_overlap;
+ bool m_reattach;
Context* m_on_finish;
bool m_legacy_parent = false;
auto ctx = create_context_callback<
CloneRequest<I>, &CloneRequest<I>::handle_attach_parent>(this);
auto req = AttachParentRequest<I>::create(
- *m_imctx, m_pspec, m_size, ctx);
+ *m_imctx, m_pspec, m_size, false, ctx);
req->send();
}
ASSERT_EQ(-ENOENT, parent_get(&ioctx, oid, &parent_image_spec));
ASSERT_EQ(-ENOENT, parent_overlap_get(&ioctx, oid, CEPH_NOSNAP,
&parent_overlap));
- ASSERT_EQ(-ENOENT, parent_attach(&ioctx, oid, parent_image_spec, 0ULL));
+ ASSERT_EQ(-ENOENT, parent_attach(&ioctx, oid, parent_image_spec, 0ULL,
+ false));
ASSERT_EQ(-ENOENT, parent_detach(&ioctx, oid));
// no layering support should fail
ASSERT_FALSE(parent_image_spec.exists());
ASSERT_EQ(0, parent_overlap_get(&ioctx, oid, CEPH_NOSNAP, &parent_overlap));
ASSERT_EQ(std::nullopt, parent_overlap);
- ASSERT_EQ(-ENOEXEC, parent_attach(&ioctx, oid, parent_image_spec, 0ULL));
+ ASSERT_EQ(-ENOEXEC, parent_attach(&ioctx, oid, parent_image_spec, 0ULL, false));
ASSERT_EQ(-ENOEXEC, parent_detach(&ioctx, oid));
// layering support available -- no pool namespaces
ASSERT_FALSE(parent_image_spec.exists());
ASSERT_EQ(0, parent_overlap_get(&ioctx, oid, CEPH_NOSNAP, &parent_overlap));
ASSERT_EQ(std::nullopt, parent_overlap);
- ASSERT_EQ(-EINVAL, parent_attach(&ioctx, oid, parent_image_spec, 0ULL));
+ ASSERT_EQ(-EINVAL, parent_attach(&ioctx, oid, parent_image_spec, 0ULL, false));
ASSERT_EQ(-ENOENT, parent_detach(&ioctx, oid));
parent_image_spec = {1, "", "parent", 2};
parent_overlap = (33 << 20) + 1;
- ASSERT_EQ(0, parent_attach(&ioctx, oid, parent_image_spec, *parent_overlap));
+ ASSERT_EQ(0, parent_attach(&ioctx, oid, parent_image_spec, *parent_overlap,
+ false));
ASSERT_EQ(-EEXIST, parent_attach(&ioctx, oid, parent_image_spec,
- *parent_overlap));
+ *parent_overlap, false));
+ ASSERT_EQ(0, parent_attach(&ioctx, oid, parent_image_spec, *parent_overlap,
+ true));
--(*parent_overlap);
cls::rbd::ParentImageSpec on_disk_parent_image_spec;
// clone across pool namespaces
parent_image_spec.pool_namespace = "ns";
parent_overlap = 31 << 20;
- ASSERT_EQ(0, parent_attach(&ioctx, oid, parent_image_spec, *parent_overlap));
+ ASSERT_EQ(0, parent_attach(&ioctx, oid, parent_image_spec, *parent_overlap,
+ false));
ASSERT_EQ(-EEXIST, parent_attach(&ioctx, oid, parent_image_spec,
- *parent_overlap));
+ *parent_overlap, false));
+ ASSERT_EQ(0, parent_attach(&ioctx, oid, parent_image_spec, *parent_overlap,
+ true));
ASSERT_EQ(0, parent_get(&ioctx, oid, &on_disk_parent_image_spec));
ASSERT_EQ(parent_image_spec, on_disk_parent_image_spec);
static AttachParentRequest* s_instance;
static AttachParentRequest* create(MockTestImageCtx&,
const cls::rbd::ParentImageSpec& pspec,
- uint64_t parent_overlap,
+ uint64_t parent_overlap, bool reattach,
Context *on_finish) {
ceph_assert(s_instance != nullptr);
s_instance->on_finish = on_finish;
C_SaferCond ctx;
auto req = MockAttachParentRequest::create(mock_image_ctx, parent_image_spec,
- 234, &ctx);
+ 234, false, &ctx);
req->send();
ASSERT_EQ(0, ctx.wait());
}
C_SaferCond ctx;
auto req = MockAttachParentRequest::create(mock_image_ctx, parent_image_spec,
- 234, &ctx);
+ 234, false, &ctx);
req->send();
ASSERT_EQ(0, ctx.wait());
}
C_SaferCond ctx;
auto req = MockAttachParentRequest::create(mock_image_ctx, parent_image_spec,
- 234, &ctx);
+ 234, false, &ctx);
req->send();
ASSERT_EQ(-EPERM, ctx.wait());
}
C_SaferCond ctx;
auto req = MockAttachParentRequest::create(mock_image_ctx, parent_image_spec,
- 234, &ctx);
+ 234, false, &ctx);
req->send();
ASSERT_EQ(-EINVAL, ctx.wait());
}
C_SaferCond ctx;
auto req = MockAttachParentRequest::create(mock_image_ctx, parent_image_spec,
- 234, &ctx);
+ 234, false, &ctx);
req->send();
ASSERT_EQ(-EXDEV, ctx.wait());
}
static AttachParentRequest* s_instance;
static AttachParentRequest* create(MockTestImageCtx&,
const cls::rbd::ParentImageSpec& pspec,
- uint64_t parent_overlap,
+ uint64_t parent_overlap, bool reattach,
Context *on_finish) {
ceph_assert(s_instance != nullptr);
s_instance->on_finish = on_finish;