]> git.proxmox.com Git - ceph.git/blob - ceph/src/librbd/crypto/FormatRequest.cc
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / librbd / crypto / FormatRequest.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 "FormatRequest.h"
5
6 #include "common/dout.h"
7 #include "common/errno.h"
8 #include "librbd/ImageCtx.h"
9 #include "librbd/Utils.h"
10 #include "librbd/crypto/EncryptionFormat.h"
11 #include "librbd/crypto/ShutDownCryptoRequest.h"
12 #include "librbd/crypto/Utils.h"
13 #include "librbd/io/AioCompletion.h"
14 #include "librbd/io/ImageDispatchSpec.h"
15 #include "librbd/io/ObjectDispatcherInterface.h"
16 #include "librbd/io/Types.h"
17
18 #define dout_subsys ceph_subsys_rbd
19 #undef dout_prefix
20 #define dout_prefix *_dout << "librbd::crypto::FormatRequest: " << this \
21 << " " << __func__ << ": "
22
23 namespace librbd {
24 namespace crypto {
25
26 using librbd::util::create_context_callback;
27
28 template <typename I>
29 FormatRequest<I>::FormatRequest(
30 I* image_ctx, EncryptionFormat format,
31 Context* on_finish) : m_image_ctx(image_ctx),
32 m_format(std::move(format)),
33 m_on_finish(on_finish) {
34 }
35
36 template <typename I>
37 void FormatRequest<I>::send() {
38 if (m_image_ctx->test_features(RBD_FEATURE_JOURNALING)) {
39 lderr(m_image_ctx->cct) << "cannot use encryption with journal" << dendl;
40 finish(-ENOTSUP);
41 return;
42 }
43
44 if (m_image_ctx->encryption_format.get() == nullptr) {
45 format();
46 return;
47 } else if (m_image_ctx->parent != nullptr) {
48 lderr(m_image_ctx->cct) << "cannot format a cloned image "
49 "while encryption is loaded"
50 << dendl;
51 finish(-EINVAL);
52 return;
53 }
54
55 auto ctx = create_context_callback<
56 FormatRequest<I>, &FormatRequest<I>::handle_shutdown_crypto>(this);
57 auto *req = ShutDownCryptoRequest<I>::create(m_image_ctx, ctx);
58 req->send();
59 }
60
61 template <typename I>
62 void FormatRequest<I>::handle_shutdown_crypto(int r) {
63 ldout(m_image_ctx->cct, 20) << "r=" << r << dendl;
64
65 if (r != 0) {
66 lderr(m_image_ctx->cct) << "unable to unload existing crypto: "
67 << cpp_strerror(r) << dendl;
68 finish(r);
69 return;
70 }
71
72 format();
73 }
74
75 template <typename I>
76 void FormatRequest<I>::format() {
77 auto ctx = create_context_callback<
78 FormatRequest<I>, &FormatRequest<I>::handle_format>(this);
79 m_format->format(m_image_ctx, ctx);
80 }
81
82 template <typename I>
83 void FormatRequest<I>::handle_format(int r) {
84 ldout(m_image_ctx->cct, 20) << "r=" << r << dendl;
85
86 if (r != 0) {
87 lderr(m_image_ctx->cct) << "unable to format image: " << cpp_strerror(r)
88 << dendl;
89 finish(r);
90 return;
91 }
92
93 flush();
94 }
95
96 template <typename I>
97 void FormatRequest<I>::flush() {
98 auto ctx = create_context_callback<
99 FormatRequest<I>, &FormatRequest<I>::handle_flush>(this);
100 auto aio_comp = io::AioCompletion::create_and_start(
101 ctx, librbd::util::get_image_ctx(m_image_ctx), io::AIO_TYPE_FLUSH);
102 auto req = io::ImageDispatchSpec::create_flush(
103 *m_image_ctx, io::IMAGE_DISPATCH_LAYER_INTERNAL_START, aio_comp,
104 io::FLUSH_SOURCE_INTERNAL, {});
105 req->send();
106 }
107
108 template <typename I>
109 void FormatRequest<I>::handle_flush(int r) {
110 ldout(m_image_ctx->cct, 20) << "r=" << r << dendl;
111
112 if (r != 0) {
113 lderr(m_image_ctx->cct) << "unable to flush image: " << cpp_strerror(r)
114 << dendl;
115 }
116
117 finish(r);
118 }
119
120 template <typename I>
121 void FormatRequest<I>::finish(int r) {
122 ldout(m_image_ctx->cct, 20) << "r=" << r << dendl;
123
124 if (r == 0 && m_image_ctx->parent == nullptr) {
125 // only load on flat images, to avoid a case where encryption
126 // is wrongfully loaded only on the child image
127 util::set_crypto(m_image_ctx, std::move(m_format));
128 }
129 m_on_finish->complete(r);
130 delete this;
131 }
132
133 } // namespace crypto
134 } // namespace librbd
135
136 template class librbd::crypto::FormatRequest<librbd::ImageCtx>;