]> git.proxmox.com Git - ceph.git/blob - ceph/src/librbd/cache/pwl/ShutdownRequest.cc
import quincy beta 17.1.0
[ceph.git] / ceph / src / librbd / cache / pwl / ShutdownRequest.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/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"
12
13 #include "librbd/cache/pwl/AbstractWriteLog.h"
14 #include "librbd/plugin/Api.h"
15
16 #define dout_subsys ceph_subsys_rbd_pwl
17 #undef dout_prefix
18 #define dout_prefix *_dout << "librbd::cache::pwl:ShutdownRequest: " \
19 << this << " " << __func__ << ": "
20
21 namespace librbd {
22 namespace cache {
23 namespace pwl {
24
25 using librbd::util::create_async_context_callback;
26 using librbd::util::create_context_callback;
27
28 template <typename I>
29 ShutdownRequest<I>* ShutdownRequest<I>::create(
30 I &image_ctx,
31 AbstractWriteLog<I> *image_cache,
32 plugin::Api<I>& plugin_api,
33 Context *on_finish) {
34 return new ShutdownRequest(image_ctx, image_cache, plugin_api, on_finish);
35 }
36
37 template <typename I>
38 ShutdownRequest<I>::ShutdownRequest(
39 I &image_ctx,
40 AbstractWriteLog<I> *image_cache,
41 plugin::Api<I>& plugin_api,
42 Context *on_finish)
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)),
47 m_error_result(0) {
48 }
49
50 template <typename I>
51 void ShutdownRequest<I>::send() {
52 send_shutdown_image_cache();
53 }
54
55 template <typename I>
56 void ShutdownRequest<I>::send_shutdown_image_cache() {
57 CephContext *cct = m_image_ctx.cct;
58 ldout(cct, 10) << dendl;
59
60 if (m_image_cache == nullptr) {
61 finish();
62 return;
63 }
64
65 using klass = ShutdownRequest<I>;
66 Context *ctx = create_context_callback<klass, &klass::handle_shutdown_image_cache>(
67 this);
68
69 m_image_cache->shut_down(ctx);
70 }
71
72 template <typename I>
73 void ShutdownRequest<I>::handle_shutdown_image_cache(int r) {
74 CephContext *cct = m_image_ctx.cct;
75 ldout(cct, 10) << dendl;
76
77 if (r < 0) {
78 lderr(cct) << "failed to shut down the image cache: " << cpp_strerror(r)
79 << dendl;
80 save_result(r);
81 finish();
82 return;
83 } else {
84 delete m_image_cache;
85 m_image_cache = nullptr;
86 }
87 send_remove_feature_bit();
88 }
89
90 template <typename I>
91 void ShutdownRequest<I>::send_remove_feature_bit() {
92 CephContext *cct = m_image_ctx.cct;
93 ldout(cct, 10) << dendl;
94
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
100 << dendl;
101
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>(
107 this);
108 ctx->complete(r);
109 }
110
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;
115
116 if (r < 0) {
117 lderr(cct) << "failed to remove the feature bit: " << cpp_strerror(r)
118 << dendl;
119 save_result(r);
120 finish();
121 return;
122 }
123 send_remove_image_cache_state();
124 }
125
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;
130
131 using klass = ShutdownRequest<I>;
132 Context *ctx = create_context_callback<klass, &klass::handle_remove_image_cache_state>(
133 this);
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);
136 }
137
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;
142
143 if (r < 0) {
144 lderr(cct) << "failed to remove the image cache state: " << cpp_strerror(r)
145 << dendl;
146 save_result(r);
147 }
148 finish();
149 }
150
151 template <typename I>
152 void ShutdownRequest<I>::finish() {
153 m_on_finish->complete(m_error_result);
154 delete this;
155 }
156
157 } // namespace pwl
158 } // namespace cache
159 } // namespace librbd
160
161 template class librbd::cache::pwl::ShutdownRequest<librbd::ImageCtx>;