1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #include "librbd/object_map/CreateRequest.h"
5 #include "include/assert.h"
6 #include "common/dout.h"
7 #include "common/errno.h"
8 #include "cls/rbd/cls_rbd_client.h"
9 #include "librbd/ImageCtx.h"
10 #include "librbd/ObjectMap.h"
11 #include "librbd/Utils.h"
13 #define dout_subsys ceph_subsys_rbd
15 #define dout_prefix *_dout << "librbd::object_map::CreateRequest: "
18 namespace object_map {
20 using util::create_context_callback;
21 using util::create_rados_callback;
24 CreateRequest<I>::CreateRequest(I *image_ctx, Context *on_finish)
25 : m_image_ctx(image_ctx), m_on_finish(on_finish) {
29 void CreateRequest<I>::send() {
30 CephContext *cct = m_image_ctx->cct;
32 uint64_t max_size = m_image_ctx->size;
35 RWLock::WLocker snap_locker(m_image_ctx->snap_lock);
36 m_snap_ids.push_back(CEPH_NOSNAP);
37 for (auto it : m_image_ctx->snap_info) {
38 max_size = MAX(max_size, it.second.size);
39 m_snap_ids.push_back(it.first);
42 if (ObjectMap<>::is_compatible(m_image_ctx->layout, max_size)) {
43 send_object_map_resize();
48 lderr(cct) << "image size not compatible with object map" << dendl;
49 m_on_finish->complete(-EINVAL);
53 void CreateRequest<I>::send_object_map_resize() {
54 CephContext *cct = m_image_ctx->cct;
55 ldout(cct, 20) << __func__ << dendl;
57 Context *ctx = create_context_callback<
58 CreateRequest<I>, &CreateRequest<I>::handle_object_map_resize>(this);
59 C_Gather *gather_ctx = new C_Gather(cct, ctx);
61 for (auto snap_id : m_snap_ids) {
62 librados::ObjectWriteOperation op;
63 uint64_t snap_size = m_image_ctx->get_image_size(snap_id);
65 cls_client::object_map_resize(&op, Striper::get_num_objects(
66 m_image_ctx->layout, snap_size),
69 std::string oid(ObjectMap<>::object_map_name(m_image_ctx->id, snap_id));
70 librados::AioCompletion *comp = create_rados_callback(gather_ctx->new_sub());
71 int r = m_image_ctx->md_ctx.aio_operate(oid, comp, &op);
75 gather_ctx->activate();
79 Context *CreateRequest<I>::handle_object_map_resize(int *result) {
80 CephContext *cct = m_image_ctx->cct;
81 ldout(cct, 20) << __func__ << ": r=" << *result << dendl;
84 lderr(cct) << "object map resize failed: " << cpp_strerror(*result)
90 } // namespace object_map
93 template class librbd::object_map::CreateRequest<librbd::ImageCtx>;