]> git.proxmox.com Git - ceph.git/blob - ceph/src/librbd/mirror/snapshot/GetImageStateRequest.cc
import 15.2.0 Octopus source
[ceph.git] / ceph / src / librbd / mirror / snapshot / GetImageStateRequest.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3
4 #include "librbd/mirror/snapshot/GetImageStateRequest.h"
5 #include "common/dout.h"
6 #include "common/errno.h"
7 #include "librbd/ImageCtx.h"
8 #include "librbd/Utils.h"
9 #include "librbd/mirror/snapshot/Types.h"
10 #include "librbd/mirror/snapshot/Utils.h"
11
12 #define dout_subsys ceph_subsys_rbd
13
14 #undef dout_prefix
15 #define dout_prefix *_dout << "librbd::mirror::snapshot::GetImageStateRequest: " \
16 << this << " " << __func__ << ": "
17
18 namespace librbd {
19 namespace mirror {
20 namespace snapshot {
21
22 using librbd::util::create_rados_callback;
23
24 template <typename I>
25 void GetImageStateRequest<I>::send() {
26 read_object();
27 }
28
29
30 template <typename I>
31 void GetImageStateRequest<I>::read_object() {
32 CephContext *cct = m_image_ctx->cct;
33
34 auto oid = util::image_state_object_name(m_image_ctx, m_snap_id,
35 m_object_index);
36 ldout(cct, 20) << oid << dendl;
37
38 librados::ObjectReadOperation op;
39 m_bl.clear();
40 op.read(0, 0, &m_bl, nullptr);
41
42 librados::AioCompletion *comp = create_rados_callback<
43 GetImageStateRequest<I>,
44 &GetImageStateRequest<I>::handle_read_object>(this);
45 int r = m_image_ctx->md_ctx.aio_operate(oid, comp, &op, nullptr);
46 ceph_assert(r == 0);
47 comp->release();
48 }
49
50 template <typename I>
51 void GetImageStateRequest<I>::handle_read_object(int r) {
52 CephContext *cct = m_image_ctx->cct;
53 ldout(cct, 20) << "r=" << r << dendl;
54
55 if (r < 0) {
56 lderr(cct) << "failed to read image state object: " << cpp_strerror(r)
57 << dendl;
58 finish(r);
59 return;
60 }
61
62 auto iter = m_bl.cbegin();
63
64 if (m_object_index == 0) {
65 ImageStateHeader header;
66 try {
67 using ceph::decode;
68 decode(header, iter);
69 } catch (const buffer::error &err) {
70 lderr(cct) << "failed to decode image state object header" << dendl;
71 finish(-EBADMSG);
72 return;
73 }
74 m_object_count = header.object_count;
75 }
76
77 bufferlist bl;
78 bl.substr_of(m_bl, iter.get_off(), m_bl.length() - iter.get_off());
79 m_state_bl.claim_append(bl);
80
81 m_object_index++;
82
83 if (m_object_index >= m_object_count) {
84 finish(0);
85 return;
86 }
87
88 read_object();
89 }
90
91 template <typename I>
92 void GetImageStateRequest<I>::finish(int r) {
93 CephContext *cct = m_image_ctx->cct;
94 ldout(cct, 20) << "r=" << r << dendl;
95
96 if (r == 0) {
97 try {
98 using ceph::decode;
99 decode(*m_image_state, m_state_bl);
100 } catch (const buffer::error &err) {
101 lderr(cct) << "failed to decode image state" << dendl;
102 r = -EBADMSG;
103 }
104 }
105
106 m_on_finish->complete(r);
107 delete this;
108 }
109
110 } // namespace snapshot
111 } // namespace mirror
112 } // namespace librbd
113
114 template class librbd::mirror::snapshot::GetImageStateRequest<librbd::ImageCtx>;