1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
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"
11 #include "librbd/cache/pwl/ImageCacheState.h"
12 #include "librbd/cache/WriteLogImageDispatch.h"
13 #include "librbd/cache/ImageWriteback.h"
15 #include "librbd/cache/pwl/rwl/WriteLog.h"
18 #ifdef WITH_RBD_SSD_CACHE
19 #include "librbd/cache/pwl/ssd/WriteLog.h"
22 #include "librbd/cache/Utils.h"
23 #include "librbd/ImageCtx.h"
24 #include "librbd/plugin/Api.h"
26 #define dout_subsys ceph_subsys_rbd_pwl
28 #define dout_prefix *_dout << "librbd::cache::pwl:InitRequest " \
29 << this << " " << __func__ << ": "
35 using librbd::util::create_async_context_callback
;
36 using librbd::util::create_context_callback
;
39 InitRequest
<I
>* InitRequest
<I
>::create(
41 cache::ImageWritebackInterface
& image_writeback
,
42 plugin::Api
<I
>& plugin_api
,
44 return new InitRequest(image_ctx
, image_writeback
, plugin_api
, on_finish
);
48 InitRequest
<I
>::InitRequest(
50 cache::ImageWritebackInterface
& image_writeback
,
51 plugin::Api
<I
>& plugin_api
,
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
)),
61 void InitRequest
<I
>::send() {
62 get_image_cache_state();
66 void InitRequest
<I
>::get_image_cache_state() {
67 CephContext
*cct
= m_image_ctx
.cct
;
68 ldout(cct
, 10) << dendl
;
71 auto cache_state
= ImageCacheState
<I
>::create_image_cache_state(
72 &m_image_ctx
, m_plugin_api
, r
);
74 if (r
< 0 || !cache_state
) {
78 } else if (!cache_state
->is_valid()) {
80 cache_state
= nullptr;
81 lderr(cct
) << "failed to get image cache state: " << cpp_strerror(r
)
88 auto cache_type
= cache_state
->get_image_cache_type();
91 case cache::IMAGE_CACHE_TYPE_RWL
:
93 new librbd::cache::pwl::rwl::WriteLog
<I
>(m_image_ctx
,
99 #ifdef WITH_RBD_SSD_CACHE
100 case cache::IMAGE_CACHE_TYPE_SSD
:
102 new librbd::cache::pwl::ssd::WriteLog
<I
>(m_image_ctx
,
110 cache_state
= nullptr;
111 save_result(-ENOENT
);
119 template <typename I
>
120 void InitRequest
<I
>::init_image_cache() {
121 CephContext
*cct
= m_image_ctx
.cct
;
122 ldout(cct
, 10) << dendl
;
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
);
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
;
136 lderr(cct
) << "failed to init image cache: " << cpp_strerror(r
)
138 delete m_image_cache
;
139 m_image_cache
= nullptr;
147 template <typename I
>
148 void InitRequest
<I
>::set_feature_bit() {
149 CephContext
*cct
= m_image_ctx
.cct
;
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
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
>(
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
;
174 lderr(cct
) << "failed to set feature bit: " << cpp_strerror(r
)
178 shutdown_image_cache();
181 // Register RWL dispatch
182 auto image_dispatch
= new cache::WriteLogImageDispatch
<I
>(
183 &m_image_ctx
, m_image_cache
, m_plugin_api
);
185 m_image_ctx
.io_image_dispatcher
->register_dispatch(image_dispatch
);
190 template <typename I
>
191 void InitRequest
<I
>::shutdown_image_cache() {
192 CephContext
*cct
= m_image_ctx
.cct
;
193 ldout(cct
, 10) << dendl
;
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
);
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
;
207 lderr(cct
) << "failed to close image cache: " << cpp_strerror(r
)
210 delete m_image_cache
;
211 m_image_cache
= nullptr;
216 template <typename I
>
217 void InitRequest
<I
>::finish() {
218 m_on_finish
->complete(m_error_result
);
224 } // namespace librbd
226 template class librbd::cache::pwl::InitRequest
<librbd::ImageCtx
>;