]>
Commit | Line | Data |
---|---|---|
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 | ||
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>; | |
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 | ||
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 | ||
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 | ||
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>; |