]> git.proxmox.com Git - ceph.git/blame - ceph/src/librbd/cache/pwl/InitRequest.cc
import quincy beta 17.1.0
[ceph.git] / ceph / src / librbd / cache / pwl / InitRequest.cc
CommitLineData
f67539c2
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 "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
31namespace librbd {
32namespace cache {
33namespace pwl {
34
35using librbd::util::create_async_context_callback;
36using librbd::util::create_context_callback;
37
38template <typename I>
39InitRequest<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
47template <typename I>
48InitRequest<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
60template <typename I>
61void InitRequest<I>::send() {
62 get_image_cache_state();
63}
64
65template <typename I>
66void 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
119template <typename I>
120void InitRequest<I>::init_image_cache() {
121 CephContext *cct = m_image_ctx.cct;
122 ldout(cct, 10) << dendl;
123
124 using klass = InitRequest<I>;
a4b75251
TL
125 Context *ctx = create_async_context_callback(m_image_ctx,
126 create_context_callback<klass, &klass::handle_init_image_cache>(this));
f67539c2
TL
127 m_image_cache->init(ctx);
128}
129
130template <typename I>
131void 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
147template <typename I>
148void 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
168template <typename I>
169void 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
f67539c2
TL
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
190template <typename I>
191void 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
201template <typename I>
202void 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
216template <typename I>
217void 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
226template class librbd::cache::pwl::InitRequest<librbd::ImageCtx>;