]>
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/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}; | |
33c7a0ef | 135 | m_plugin_api.execute_image_metadata_remove(&m_image_ctx, PERSISTENT_CACHE_STATE, ctx); |
f67539c2 TL |
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>; |