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/ShutdownRequest.h"
5 #include "librbd/ImageCtx.h"
6 #include "librbd/Utils.h"
7 #include "common/dout.h"
8 #include "common/errno.h"
9 #include "librbd/Operations.h"
10 #include "librbd/asio/ContextWQ.h"
11 #include "librbd/cache/Types.h"
13 #include "librbd/cache/pwl/AbstractWriteLog.h"
14 #include "librbd/plugin/Api.h"
16 #define dout_subsys ceph_subsys_rbd_pwl
18 #define dout_prefix *_dout << "librbd::cache::pwl:ShutdownRequest: " \
19 << this << " " << __func__ << ": "
25 using librbd::util::create_async_context_callback
;
26 using librbd::util::create_context_callback
;
29 ShutdownRequest
<I
>* ShutdownRequest
<I
>::create(
31 AbstractWriteLog
<I
> *image_cache
,
32 plugin::Api
<I
>& plugin_api
,
34 return new ShutdownRequest(image_ctx
, image_cache
, plugin_api
, on_finish
);
38 ShutdownRequest
<I
>::ShutdownRequest(
40 AbstractWriteLog
<I
> *image_cache
,
41 plugin::Api
<I
>& plugin_api
,
43 : m_image_ctx(image_ctx
),
44 m_image_cache(image_cache
),
45 m_plugin_api(plugin_api
),
46 m_on_finish(create_async_context_callback(image_ctx
, on_finish
)),
51 void ShutdownRequest
<I
>::send() {
52 send_shutdown_image_cache();
56 void ShutdownRequest
<I
>::send_shutdown_image_cache() {
57 CephContext
*cct
= m_image_ctx
.cct
;
58 ldout(cct
, 10) << dendl
;
60 if (m_image_cache
== nullptr) {
65 using klass
= ShutdownRequest
<I
>;
66 Context
*ctx
= create_context_callback
<klass
, &klass::handle_shutdown_image_cache
>(
69 m_image_cache
->shut_down(ctx
);
73 void ShutdownRequest
<I
>::handle_shutdown_image_cache(int r
) {
74 CephContext
*cct
= m_image_ctx
.cct
;
75 ldout(cct
, 10) << dendl
;
78 lderr(cct
) << "failed to shut down the image cache: " << cpp_strerror(r
)
85 m_image_cache
= nullptr;
87 send_remove_feature_bit();
91 void ShutdownRequest
<I
>::send_remove_feature_bit() {
92 CephContext
*cct
= m_image_ctx
.cct
;
93 ldout(cct
, 10) << dendl
;
95 uint64_t new_features
= m_image_ctx
.features
& ~RBD_FEATURE_DIRTY_CACHE
;
96 uint64_t features_mask
= RBD_FEATURE_DIRTY_CACHE
;
97 ldout(cct
, 10) << "old_features=" << m_image_ctx
.features
98 << ", new_features=" << new_features
99 << ", features_mask=" << features_mask
102 int r
= librbd::cls_client::set_features(&m_image_ctx
.md_ctx
, m_image_ctx
.header_oid
,
103 new_features
, features_mask
);
104 m_image_ctx
.features
&= ~RBD_FEATURE_DIRTY_CACHE
;
105 using klass
= ShutdownRequest
<I
>;
106 Context
*ctx
= create_context_callback
<klass
, &klass::handle_remove_feature_bit
>(
111 template <typename I
>
112 void ShutdownRequest
<I
>::handle_remove_feature_bit(int r
) {
113 CephContext
*cct
= m_image_ctx
.cct
;
114 ldout(cct
, 10) << dendl
;
117 lderr(cct
) << "failed to remove the feature bit: " << cpp_strerror(r
)
123 send_remove_image_cache_state();
126 template <typename I
>
127 void ShutdownRequest
<I
>::send_remove_image_cache_state() {
128 CephContext
*cct
= m_image_ctx
.cct
;
129 ldout(cct
, 10) << dendl
;
131 using klass
= ShutdownRequest
<I
>;
132 Context
*ctx
= create_context_callback
<klass
, &klass::handle_remove_image_cache_state
>(
134 std::shared_lock owner_lock
{m_image_ctx
.owner_lock
};
135 m_plugin_api
.execute_image_metadata_remove(&m_image_ctx
, IMAGE_CACHE_STATE
, ctx
);
138 template <typename I
>
139 void ShutdownRequest
<I
>::handle_remove_image_cache_state(int r
) {
140 CephContext
*cct
= m_image_ctx
.cct
;
141 ldout(cct
, 10) << dendl
;
144 lderr(cct
) << "failed to remove the image cache state: " << cpp_strerror(r
)
151 template <typename I
>
152 void ShutdownRequest
<I
>::finish() {
153 m_on_finish
->complete(m_error_result
);
159 } // namespace librbd
161 template class librbd::cache::pwl::ShutdownRequest
<librbd::ImageCtx
>;