]> git.proxmox.com Git - ceph.git/blob - ceph/src/librbd/cache/pwl/InitRequest.cc
import quincy beta 17.1.0
[ceph.git] / ceph / src / librbd / cache / pwl / InitRequest.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/cache/pwl/InitRequest.h"
5 #include "librbd/io/ImageDispatcher.h"
6 #include "librbd/Utils.h"
7 #include "common/dout.h"
8 #include "common/errno.h"
9 #include "librbd/asio/ContextWQ.h"
10
11 #include "librbd/cache/pwl/ImageCacheState.h"
12 #include "librbd/cache/WriteLogImageDispatch.h"
13 #include "librbd/cache/ImageWriteback.h"
14 #ifdef WITH_RBD_RWL
15 #include "librbd/cache/pwl/rwl/WriteLog.h"
16 #endif
17
18 #ifdef WITH_RBD_SSD_CACHE
19 #include "librbd/cache/pwl/ssd/WriteLog.h"
20 #endif
21
22 #include "librbd/cache/Utils.h"
23 #include "librbd/ImageCtx.h"
24 #include "librbd/plugin/Api.h"
25
26 #define dout_subsys ceph_subsys_rbd_pwl
27 #undef dout_prefix
28 #define dout_prefix *_dout << "librbd::cache::pwl:InitRequest " \
29 << this << " " << __func__ << ": "
30
31 namespace librbd {
32 namespace cache {
33 namespace pwl {
34
35 using librbd::util::create_async_context_callback;
36 using librbd::util::create_context_callback;
37
38 template <typename I>
39 InitRequest<I>* InitRequest<I>::create(
40 I &image_ctx,
41 cache::ImageWritebackInterface& image_writeback,
42 plugin::Api<I>& plugin_api,
43 Context *on_finish) {
44 return new InitRequest(image_ctx, image_writeback, plugin_api, on_finish);
45 }
46
47 template <typename I>
48 InitRequest<I>::InitRequest(
49 I &image_ctx,
50 cache::ImageWritebackInterface& image_writeback,
51 plugin::Api<I>& plugin_api,
52 Context *on_finish)
53 : m_image_ctx(image_ctx),
54 m_image_writeback(image_writeback),
55 m_plugin_api(plugin_api),
56 m_on_finish(create_async_context_callback(image_ctx, on_finish)),
57 m_error_result(0) {
58 }
59
60 template <typename I>
61 void InitRequest<I>::send() {
62 get_image_cache_state();
63 }
64
65 template <typename I>
66 void InitRequest<I>::get_image_cache_state() {
67 CephContext *cct = m_image_ctx.cct;
68 ldout(cct, 10) << dendl;
69
70 int r;
71 auto cache_state = ImageCacheState<I>::create_image_cache_state(
72 &m_image_ctx, m_plugin_api, r);
73
74 if (r < 0 || !cache_state) {
75 save_result(r);
76 finish();
77 return;
78 } else if (!cache_state->is_valid()) {
79 delete cache_state;
80 cache_state = nullptr;
81 lderr(cct) << "failed to get image cache state: " << cpp_strerror(r)
82 << dendl;
83 save_result(-ENOENT);
84 finish();
85 return;
86 }
87
88 auto cache_type = cache_state->get_image_cache_type();
89 switch(cache_type) {
90 #ifdef WITH_RBD_RWL
91 case cache::IMAGE_CACHE_TYPE_RWL:
92 m_image_cache =
93 new librbd::cache::pwl::rwl::WriteLog<I>(m_image_ctx,
94 cache_state,
95 m_image_writeback,
96 m_plugin_api);
97 break;
98 #endif
99 #ifdef WITH_RBD_SSD_CACHE
100 case cache::IMAGE_CACHE_TYPE_SSD:
101 m_image_cache =
102 new librbd::cache::pwl::ssd::WriteLog<I>(m_image_ctx,
103 cache_state,
104 m_image_writeback,
105 m_plugin_api);
106 break;
107 #endif
108 default:
109 delete cache_state;
110 cache_state = nullptr;
111 save_result(-ENOENT);
112 finish();
113 return;
114 }
115
116 init_image_cache();
117 }
118
119 template <typename I>
120 void InitRequest<I>::init_image_cache() {
121 CephContext *cct = m_image_ctx.cct;
122 ldout(cct, 10) << dendl;
123
124 using klass = InitRequest<I>;
125 Context *ctx = create_async_context_callback(m_image_ctx,
126 create_context_callback<klass, &klass::handle_init_image_cache>(this));
127 m_image_cache->init(ctx);
128 }
129
130 template <typename I>
131 void InitRequest<I>::handle_init_image_cache(int r) {
132 CephContext *cct = m_image_ctx.cct;
133 ldout(cct, 10) << dendl;
134
135 if (r < 0) {
136 lderr(cct) << "failed to init image cache: " << cpp_strerror(r)
137 << dendl;
138 delete m_image_cache;
139 m_image_cache = nullptr;
140 save_result(r);
141 finish();
142 return;
143 }
144 set_feature_bit();
145 }
146
147 template <typename I>
148 void InitRequest<I>::set_feature_bit() {
149 CephContext *cct = m_image_ctx.cct;
150
151 uint64_t new_features = m_image_ctx.features | RBD_FEATURE_DIRTY_CACHE;
152 uint64_t features_mask = RBD_FEATURE_DIRTY_CACHE;
153 ldout(cct, 10) << "old_features=" << m_image_ctx.features
154 << ", new_features=" << new_features
155 << ", features_mask=" << features_mask
156 << dendl;
157
158 int r = librbd::cls_client::set_features(&m_image_ctx.md_ctx,
159 m_image_ctx.header_oid,
160 new_features, features_mask);
161 m_image_ctx.features |= RBD_FEATURE_DIRTY_CACHE;
162 using klass = InitRequest<I>;
163 Context *ctx = create_context_callback<klass, &klass::handle_set_feature_bit>(
164 this);
165 ctx->complete(r);
166 }
167
168 template <typename I>
169 void InitRequest<I>::handle_set_feature_bit(int r) {
170 CephContext *cct = m_image_ctx.cct;
171 ldout(cct, 10) << "r=" << r << dendl;
172
173 if (r < 0) {
174 lderr(cct) << "failed to set feature bit: " << cpp_strerror(r)
175 << dendl;
176 save_result(r);
177
178 shutdown_image_cache();
179 }
180
181 // Register RWL dispatch
182 auto image_dispatch = new cache::WriteLogImageDispatch<I>(
183 &m_image_ctx, m_image_cache, m_plugin_api);
184
185 m_image_ctx.io_image_dispatcher->register_dispatch(image_dispatch);
186
187 finish();
188 }
189
190 template <typename I>
191 void InitRequest<I>::shutdown_image_cache() {
192 CephContext *cct = m_image_ctx.cct;
193 ldout(cct, 10) << dendl;
194
195 using klass = InitRequest<I>;
196 Context *ctx = create_context_callback<
197 klass, &klass::handle_shutdown_image_cache>(this);
198 m_image_cache->shut_down(ctx);
199 }
200
201 template <typename I>
202 void InitRequest<I>::handle_shutdown_image_cache(int r) {
203 CephContext *cct = m_image_ctx.cct;
204 ldout(cct, 10) << dendl;
205
206 if (r < 0) {
207 lderr(cct) << "failed to close image cache: " << cpp_strerror(r)
208 << dendl;
209 }
210 delete m_image_cache;
211 m_image_cache = nullptr;
212
213 finish();
214 }
215
216 template <typename I>
217 void InitRequest<I>::finish() {
218 m_on_finish->complete(m_error_result);
219 delete this;
220 }
221
222 } // namespace pwl
223 } // namespace cache
224 } // namespace librbd
225
226 template class librbd::cache::pwl::InitRequest<librbd::ImageCtx>;