]> git.proxmox.com Git - ceph.git/blame - ceph/src/librbd/deep_copy/MetadataCopyRequest.cc
import 15.2.0 Octopus source
[ceph.git] / ceph / src / librbd / deep_copy / MetadataCopyRequest.cc
CommitLineData
11fdf7f2
TL
1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2// vim: ts=8 sw=2 smarttab
3
4#include "MetadataCopyRequest.h"
5#include "common/dout.h"
6#include "common/errno.h"
7#include "cls/rbd/cls_rbd_client.h"
8#include "librbd/Utils.h"
9f95a23c 9#include "librbd/image/GetMetadataRequest.h"
11fdf7f2
TL
10
11#define dout_subsys ceph_subsys_rbd
12#undef dout_prefix
13#define dout_prefix *_dout << "librbd::deep_copy::MetadataCopyRequest: " \
14 << this << " " << __func__ << ": "
15
16namespace librbd {
17namespace deep_copy {
18
19namespace {
20
21const uint64_t MAX_METADATA_ITEMS = 128;
22
23} // anonymous namespace
24
9f95a23c 25using librbd::util::create_context_callback;
11fdf7f2
TL
26using librbd::util::create_rados_callback;
27
28template <typename I>
29MetadataCopyRequest<I>::MetadataCopyRequest(I *src_image_ctx, I *dst_image_ctx,
30 Context *on_finish)
31 : m_src_image_ctx(src_image_ctx), m_dst_image_ctx(dst_image_ctx),
32 m_on_finish(on_finish), m_cct(dst_image_ctx->cct) {
33}
34
35template <typename I>
36void MetadataCopyRequest<I>::send() {
37 list_src_metadata();
38}
39
40template <typename I>
41void MetadataCopyRequest<I>::list_src_metadata() {
42 ldout(m_cct, 20) << "start_key=" << m_last_metadata_key << dendl;
43
9f95a23c
TL
44 m_metadata.clear();
45 auto ctx = create_context_callback<
11fdf7f2
TL
46 MetadataCopyRequest<I>,
47 &MetadataCopyRequest<I>::handle_list_src_metadata>(this);
9f95a23c
TL
48 auto req = image::GetMetadataRequest<I>::create(
49 m_src_image_ctx->md_ctx, m_src_image_ctx->header_oid, true, "",
50 m_last_metadata_key, MAX_METADATA_ITEMS, &m_metadata, ctx);
51 req->send();
11fdf7f2
TL
52}
53
54template <typename I>
55void MetadataCopyRequest<I>::handle_list_src_metadata(int r) {
56 ldout(m_cct, 20) << "r=" << r << dendl;
57
11fdf7f2
TL
58 if (r < 0) {
59 lderr(m_cct) << "failed to retrieve metadata: " << cpp_strerror(r) << dendl;
60 finish(r);
61 return;
62 }
63
9f95a23c 64 if (m_metadata.empty()) {
11fdf7f2
TL
65 finish(0);
66 return;
67 }
68
9f95a23c
TL
69 m_last_metadata_key = m_metadata.rbegin()->first;
70 m_more_metadata = (m_metadata.size() >= MAX_METADATA_ITEMS);
71 set_dst_metadata();
11fdf7f2
TL
72}
73
74template <typename I>
9f95a23c
TL
75void MetadataCopyRequest<I>::set_dst_metadata() {
76 ldout(m_cct, 20) << "count=" << m_metadata.size() << dendl;
11fdf7f2
TL
77
78 librados::ObjectWriteOperation op;
9f95a23c 79 librbd::cls_client::metadata_set(&op, m_metadata);
11fdf7f2
TL
80
81 librados::AioCompletion *aio_comp = create_rados_callback<
82 MetadataCopyRequest<I>,
83 &MetadataCopyRequest<I>::handle_set_dst_metadata>(this);
84 m_dst_image_ctx->md_ctx.aio_operate(m_dst_image_ctx->header_oid, aio_comp,
85 &op);
86 aio_comp->release();
87}
88
89template <typename I>
90void MetadataCopyRequest<I>::handle_set_dst_metadata(int r) {
91 ldout(m_cct, 20) << "r=" << r << dendl;
92
93 if (r < 0) {
94 lderr(m_cct) << "failed to set metadata: " << cpp_strerror(r) << dendl;
95 finish(r);
96 return;
97 }
98
99 if (m_more_metadata) {
100 list_src_metadata();
101 return;
102 }
103
104 finish(0);
105}
106
107template <typename I>
108void MetadataCopyRequest<I>::finish(int r) {
109 ldout(m_cct, 20) << "r=" << r << dendl;
110 m_on_finish->complete(r);
111 delete this;
112}
113
114} // namespace deep_copy
115} // namespace librbd
116
117template class librbd::deep_copy::MetadataCopyRequest<librbd::ImageCtx>;