exclusive_lock/PreReleaseRequest.cc
exclusive_lock/StandardPolicy.cc
group/ListSnapshotsRequest.cc
+ group/AddImageRequest.cc
+ group/RemoveImageRequest.cc
image/AttachChildRequest.cc
image/AttachParentRequest.cc
image/CloneRequest.cc
--- /dev/null
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "librbd/group/AddImageRequest.h"
+#include "include/ceph_assert.h"
+#include "common/dout.h"
+#include "common/errno.h"
+#include "common/ceph_context.h"
+#include "cls/rbd/cls_rbd_client.h"
+#include "librbd/Utils.h"
+
+#define dout_subsys ceph_subsys_rbd
+#undef dout_prefix
+#define dout_prefix *_dout << "librbd::group::AddImageRequest: " << this \
+ << " " << __func__ << ": "
+
+namespace librbd {
+namespace group {
+
+using util::create_rados_callback;
+
+template <typename I>
+void AddImageRequest<I>::send() {
+ pre_link();
+}
+
+template <typename I>
+void AddImageRequest<I>::pre_link() {
+ CephContext *cct = (CephContext *)m_image_io_ctx.cct();
+ ldout(cct, 10) << dendl;
+
+ librados::ObjectWriteOperation op;
+ cls_client::group_image_set(
+ &op, {m_image_id, m_image_io_ctx.get_id(),
+ cls::rbd::GROUP_IMAGE_LINK_STATE_INCOMPLETE});
+ auto comp = create_rados_callback<
+ AddImageRequest<I>, &AddImageRequest<I>::handle_pre_link>(this);
+
+ int r = m_group_io_ctx.aio_operate(util::group_header_name(m_group_id), comp,
+ &op);
+ ceph_assert(r == 0);
+ comp->release();
+}
+
+template <typename I>
+void AddImageRequest<I>::handle_pre_link(int r) {
+ CephContext *cct = (CephContext *)m_image_io_ctx.cct();
+ ldout(cct, 10) << "r=" << r << dendl;
+
+ if (r < 0) {
+ lderr(cct) << "failed to pre link group image: " << cpp_strerror(r)
+ << dendl;
+ finish(r);
+ return;
+ }
+
+ add_group();
+}
+
+template <typename I>
+void AddImageRequest<I>::add_group() {
+ CephContext *cct = (CephContext *)m_image_io_ctx.cct();
+ ldout(cct, 10) << dendl;
+
+ librados::ObjectWriteOperation op;
+ cls_client::image_group_add(&op, {m_group_id, m_group_io_ctx.get_id()});
+ auto comp = create_rados_callback<
+ AddImageRequest<I>, &AddImageRequest<I>::handle_add_group>(this);
+
+ int r = m_image_io_ctx.aio_operate(util::header_name(m_image_id), comp, &op);
+ ceph_assert(r == 0);
+ comp->release();
+}
+
+template <typename I>
+void AddImageRequest<I>::handle_add_group(int r) {
+ CephContext *cct = (CephContext *)m_image_io_ctx.cct();
+ ldout(cct, 10) << "r=" << r << dendl;
+
+ if (r < 0) {
+ lderr(cct) << "failed to add image group: " << cpp_strerror(r) << dendl;
+ m_ret_val = r;
+ }
+
+ post_link();
+}
+
+template <typename I>
+void AddImageRequest<I>::post_link() {
+ CephContext *cct = (CephContext *)m_image_io_ctx.cct();
+ ldout(cct, 10) << dendl;
+
+ librados::ObjectWriteOperation op;
+
+ if (m_ret_val < 0) {
+ cls_client::group_image_remove(&op, {m_image_id, m_image_io_ctx.get_id()});
+ } else {
+ cls_client::group_image_set(
+ &op, {m_image_id, m_image_io_ctx.get_id(),
+ cls::rbd::GROUP_IMAGE_LINK_STATE_ATTACHED});
+ }
+ auto comp = create_rados_callback<
+ AddImageRequest<I>, &AddImageRequest<I>::handle_post_link>(this);
+
+ int r = m_group_io_ctx.aio_operate(util::group_header_name(m_group_id), comp,
+ &op);
+ ceph_assert(r == 0);
+ comp->release();
+}
+
+template <typename I>
+void AddImageRequest<I>::handle_post_link(int r) {
+ CephContext *cct = (CephContext *)m_image_io_ctx.cct();
+ ldout(cct, 10) << "r=" << r << dendl;
+
+ if (r < 0) {
+ lderr(cct) << "failed to post link group image: " << cpp_strerror(r)
+ << dendl;
+ if (m_ret_val == 0) {
+ m_ret_val = r;
+ }
+ }
+
+ finish(m_ret_val);
+}
+
+template <typename I>
+void AddImageRequest<I>::finish(int r) {
+ CephContext *cct = (CephContext *)m_image_io_ctx.cct();
+ ldout(cct, 10) << "r=" << r << dendl;
+
+ m_on_finish->complete(r);
+}
+
+} // namespace group
+} // namespace librbd
+
+template class librbd::group::AddImageRequest<librbd::ImageCtx>;
--- /dev/null
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef CEPH_LIBRBD_GROUP_ADD_IMAGE_REQUEST_H
+#define CEPH_LIBRBD_GROUP_ADD_IMAGE_REQUEST_H
+
+#include "include/int_types.h"
+#include "include/types.h"
+#include "include/rados/librados.hpp"
+#include <string>
+
+class Context;
+
+namespace librbd {
+
+struct ImageCtx;
+
+namespace group {
+
+template <typename ImageCtxT = librbd::ImageCtx>
+class AddImageRequest {
+public:
+ static AddImageRequest *create(librados::IoCtx &group_io_ctx,
+ const std::string &group_id,
+ librados::IoCtx &image_io_ctx,
+ const std::string &image_id,
+ Context *on_finish) {
+ return new AddImageRequest(group_io_ctx, group_id, image_io_ctx, image_id,
+ on_finish);
+ }
+
+ AddImageRequest(librados::IoCtx &group_io_ctx,
+ const std::string &group_id,
+ librados::IoCtx &image_io_ctx,
+ const std::string &image_id,
+ Context *on_finish)
+ : m_group_io_ctx(group_io_ctx), m_group_id(group_id),
+ m_image_io_ctx(image_io_ctx), m_image_id(image_id),
+ m_on_finish(on_finish) {
+ }
+
+ void send();
+
+private:
+ /**
+ * @verbatim
+ *
+ * <start>
+ * |
+ * v
+ * PRE_LINK
+ * |
+ * v
+ * ADD_GROUP
+ * |
+ * v
+ * POST_LINK
+ * |
+ * v
+ * <finish>
+ *
+ * @endverbatim
+ */
+
+ librados::IoCtx &m_group_io_ctx;
+ const std::string m_group_id;
+ librados::IoCtx &m_image_io_ctx;
+ const std::string m_image_id;
+ Context *m_on_finish;
+
+ int m_ret_val = 0;
+
+ void pre_link();
+ void handle_pre_link(int r);
+
+ void add_group();
+ void handle_add_group(int r);
+
+ void post_link();
+ void handle_post_link(int r);
+
+ void finish(int r);
+};
+
+} // namespace group
+} // namespace librbd
+
+extern template class librbd::group::AddImageRequest<librbd::ImageCtx>;
+
+#endif // CEPH_LIBRBD_GROUP_ADD_IMAGE_REQUEST_H
--- /dev/null
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "librbd/group/RemoveImageRequest.h"
+#include "include/ceph_assert.h"
+#include "common/dout.h"
+#include "common/errno.h"
+#include "common/ceph_context.h"
+#include "cls/rbd/cls_rbd_client.h"
+#include "librbd/Utils.h"
+
+#define dout_subsys ceph_subsys_rbd
+#undef dout_prefix
+#define dout_prefix *_dout << "librbd::group::RemoveImageRequest: " << this \
+ << " " << __func__ << ": "
+
+namespace librbd {
+namespace group {
+
+using librbd::util::create_rados_callback;
+
+template <typename I>
+void RemoveImageRequest<I>::send() {
+ pre_unlink();
+}
+
+template <typename I>
+void RemoveImageRequest<I>::pre_unlink() {
+ CephContext *cct = (CephContext *)m_image_io_ctx.cct();
+ ldout(cct, 10) << dendl;
+
+ librados::ObjectWriteOperation op;
+ cls_client::group_image_set(
+ &op, {m_image_id, m_image_io_ctx.get_id(),
+ cls::rbd::GROUP_IMAGE_LINK_STATE_INCOMPLETE});
+ auto comp = create_rados_callback<
+ RemoveImageRequest<I>, &RemoveImageRequest<I>::handle_pre_unlink>(this);
+
+ int r = m_group_io_ctx.aio_operate(util::group_header_name(m_group_id), comp,
+ &op);
+ ceph_assert(r == 0);
+ comp->release();
+}
+
+template <typename I>
+void RemoveImageRequest<I>::handle_pre_unlink(int r) {
+ CephContext *cct = (CephContext *)m_image_io_ctx.cct();
+ ldout(cct, 10) << "r=" << r << dendl;
+
+ if (r < 0) {
+ lderr(cct) << "failed to pre unlink group image: " << cpp_strerror(r)
+ << dendl;
+ finish(r);
+ return;
+ }
+
+ remove_group();
+}
+
+template <typename I>
+void RemoveImageRequest<I>::remove_group() {
+ CephContext *cct = (CephContext *)m_image_io_ctx.cct();
+ ldout(cct, 10) << dendl;
+
+ librados::ObjectWriteOperation op;
+ cls_client::image_group_remove(&op, {m_group_id, m_group_io_ctx.get_id()});
+ auto comp = create_rados_callback<
+ RemoveImageRequest<I>, &RemoveImageRequest<I>::handle_remove_group>(this);
+
+ int r = m_image_io_ctx.aio_operate(util::header_name(m_image_id), comp, &op);
+ ceph_assert(r == 0);
+ comp->release();
+}
+
+template <typename I>
+void RemoveImageRequest<I>::handle_remove_group(int r) {
+ CephContext *cct = (CephContext *)m_image_io_ctx.cct();
+ ldout(cct, 10) << "r=" << r << dendl;
+
+ if (r < 0) {
+ lderr(cct) << "failed to remove image group: " << cpp_strerror(r) << dendl;
+ finish(r);
+ return;
+ }
+
+ post_unlink();
+}
+
+template <typename I>
+void RemoveImageRequest<I>::post_unlink() {
+ CephContext *cct = (CephContext *)m_image_io_ctx.cct();
+ ldout(cct, 10) << dendl;
+
+ librados::ObjectWriteOperation op;
+ cls_client::group_image_remove(&op, {m_image_id, m_image_io_ctx.get_id()});
+ auto comp = create_rados_callback<
+ RemoveImageRequest<I>, &RemoveImageRequest<I>::handle_post_unlink>(this);
+
+ int r = m_group_io_ctx.aio_operate(util::group_header_name(m_group_id), comp,
+ &op);
+ ceph_assert(r == 0);
+ comp->release();
+}
+
+template <typename I>
+void RemoveImageRequest<I>::handle_post_unlink(int r) {
+ CephContext *cct = (CephContext *)m_image_io_ctx.cct();
+ ldout(cct, 10) << "r=" << r << dendl;
+
+ if (r < 0) {
+ lderr(cct) << "failed to post unlink group image: " << cpp_strerror(r)
+ << dendl;
+ finish(r);
+ return;
+ }
+
+ finish(0);
+}
+
+template <typename I>
+void RemoveImageRequest<I>::finish(int r) {
+ CephContext *cct = (CephContext *)m_image_io_ctx.cct();
+ ldout(cct, 10) << "r=" << r << dendl;
+
+ m_on_finish->complete(r);
+}
+
+} // namespace group
+} // namespace librbd
+
+template class librbd::group::RemoveImageRequest<librbd::ImageCtx>;
--- /dev/null
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef CEPH_LIBRBD_GROUP_REMOVE_IMAGE_REQUEST_H
+#define CEPH_LIBRBD_GROUP_REMOVE_IMAGE_REQUEST_H
+
+#include "include/int_types.h"
+#include "include/types.h"
+#include "include/rados/librados.hpp"
+#include <string>
+
+class Context;
+
+namespace librbd {
+
+struct ImageCtx;
+
+namespace group {
+
+template <typename ImageCtxT = librbd::ImageCtx>
+class RemoveImageRequest {
+public:
+ static RemoveImageRequest *create(librados::IoCtx &group_io_ctx,
+ const std::string &group_id,
+ librados::IoCtx &image_io_ctx,
+ const std::string &image_id,
+ Context *on_finish) {
+ return new RemoveImageRequest(group_io_ctx, group_id, image_io_ctx,
+ image_id, on_finish);
+ }
+
+ RemoveImageRequest(librados::IoCtx &group_io_ctx,
+ const std::string &group_id,
+ librados::IoCtx &image_io_ctx,
+ const std::string &image_id,
+ Context *on_finish)
+ : m_group_io_ctx(group_io_ctx), m_group_id(group_id),
+ m_image_io_ctx(image_io_ctx), m_image_id(image_id),
+ m_on_finish(on_finish) {
+ }
+
+ void send();
+
+private:
+ /**
+ * @verbatim
+ *
+ * <start>
+ * |
+ * v
+ * PRE_UNLINK
+ * |
+ * v
+ * REMOVE_GROUP
+ * |
+ * v
+ * POST_UNLINK
+ * |
+ * v
+ * <finish>
+ *
+ * @endverbatim
+ */
+
+ librados::IoCtx &m_group_io_ctx;
+ const std::string m_group_id;
+ librados::IoCtx &m_image_io_ctx;
+ const std::string m_image_id;
+ Context *m_on_finish;
+
+ void pre_unlink();
+ void handle_pre_unlink(int r);
+
+ void remove_group();
+ void handle_remove_group(int r);
+
+ void post_unlink();
+ void handle_post_unlink(int r);
+
+ void finish(int r);
+};
+
+} // namespace group
+} // namespace librbd
+
+extern template class librbd::group::RemoveImageRequest<librbd::ImageCtx>;
+
+#endif // CEPH_LIBRBD_GROUP_REMOVE_IMAGE_REQUEST_H