]>
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 "common/dout.h" | |
5 | #include "common/errno.h" | |
6 | #include "common/hostname.h" | |
7 | #include "librbd/asio/ContextWQ.h" | |
8 | #include "librbd/cache/pwl/DiscardRequest.h" | |
9 | ||
10 | #if __has_include(<filesystem>) | |
11 | #include <filesystem> | |
12 | namespace fs = std::filesystem; | |
13 | #elif __has_include(<experimental/filesystem>) | |
14 | #include <experimental/filesystem> | |
15 | namespace fs = std::experimental::filesystem; | |
16 | #endif | |
17 | ||
18 | #include "librbd/cache/pwl/ImageCacheState.h" | |
19 | ||
20 | #include "librbd/cache/Types.h" | |
21 | #include "librbd/io/ImageDispatcherInterface.h" | |
22 | #include "librbd/ImageCtx.h" | |
23 | #include "librbd/Utils.h" | |
24 | ||
25 | ||
26 | #define dout_subsys ceph_subsys_rbd_pwl | |
27 | #undef dout_prefix | |
28 | #define dout_prefix *_dout << "librbd::cache::pwl:DiscardRequest: " \ | |
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 | DiscardRequest<I>* DiscardRequest<I>::create( | |
40 | I &image_ctx, | |
41 | plugin::Api<I>& plugin_api, | |
42 | Context *on_finish) { | |
43 | return new DiscardRequest(image_ctx, plugin_api, on_finish); | |
44 | } | |
45 | ||
46 | template <typename I> | |
47 | DiscardRequest<I>::DiscardRequest( | |
48 | I &image_ctx, | |
49 | plugin::Api<I>& plugin_api, | |
50 | Context *on_finish) | |
51 | : m_image_ctx(image_ctx), | |
52 | m_plugin_api(plugin_api), | |
53 | m_on_finish(create_async_context_callback(image_ctx, on_finish)), | |
54 | m_error_result(0) { | |
55 | } | |
56 | ||
57 | template <typename I> | |
58 | void DiscardRequest<I>::send() { | |
59 | delete_image_cache_file(); | |
60 | } | |
61 | ||
62 | template <typename I> | |
63 | void DiscardRequest<I>::delete_image_cache_file() { | |
64 | CephContext *cct = m_image_ctx.cct; | |
65 | ldout(cct, 10) << dendl; | |
66 | ||
67 | m_cache_state = ImageCacheState<I>::get_image_cache_state(&m_image_ctx, m_plugin_api); | |
68 | if (!m_cache_state) { | |
69 | remove_feature_bit(); | |
70 | return; | |
71 | } | |
72 | if (m_cache_state->present && | |
73 | !m_cache_state->host.compare(ceph_get_short_hostname()) && | |
74 | fs::exists(m_cache_state->path)) { | |
75 | fs::remove(m_cache_state->path); | |
76 | } | |
77 | ||
78 | remove_image_cache_state(); | |
79 | } | |
80 | ||
81 | template <typename I> | |
82 | void DiscardRequest<I>::remove_image_cache_state() { | |
83 | CephContext *cct = m_image_ctx.cct; | |
84 | ldout(cct, 10) << dendl; | |
85 | ||
86 | using klass = DiscardRequest<I>; | |
87 | Context *ctx = create_context_callback<klass, &klass::handle_remove_image_cache_state>( | |
88 | this); | |
89 | ||
90 | m_cache_state->clear_image_cache_state(ctx); | |
91 | } | |
92 | ||
93 | template <typename I> | |
94 | void DiscardRequest<I>::handle_remove_image_cache_state(int r) { | |
95 | CephContext *cct = m_image_ctx.cct; | |
96 | ldout(cct, 10) << dendl; | |
97 | ||
98 | if (r < 0) { | |
99 | lderr(cct) << "failed to remove the image cache state: " << cpp_strerror(r) | |
100 | << dendl; | |
101 | save_result(r); | |
102 | finish(); | |
103 | return; | |
104 | } | |
105 | ||
106 | remove_feature_bit(); | |
107 | } | |
108 | ||
109 | template <typename I> | |
110 | void DiscardRequest<I>::remove_feature_bit() { | |
111 | CephContext *cct = m_image_ctx.cct; | |
112 | ldout(cct, 10) << dendl; | |
113 | ||
114 | if (!(m_image_ctx.features &&RBD_FEATURE_DIRTY_CACHE)) { | |
115 | finish(); | |
116 | return; | |
117 | } | |
118 | uint64_t new_features = m_image_ctx.features & ~RBD_FEATURE_DIRTY_CACHE; | |
119 | uint64_t features_mask = RBD_FEATURE_DIRTY_CACHE; | |
120 | ldout(cct, 10) << "old_features=" << m_image_ctx.features | |
121 | << ", new_features=" << new_features | |
122 | << ", features_mask=" << features_mask | |
123 | << dendl; | |
124 | ||
125 | int r = librbd::cls_client::set_features(&m_image_ctx.md_ctx, m_image_ctx.header_oid, | |
126 | new_features, features_mask); | |
127 | m_image_ctx.features &= ~RBD_FEATURE_DIRTY_CACHE; | |
128 | using klass = DiscardRequest<I>; | |
129 | Context *ctx = create_context_callback<klass, &klass::handle_remove_feature_bit>( | |
130 | this); | |
131 | ctx->complete(r); | |
132 | } | |
133 | ||
134 | template <typename I> | |
135 | void DiscardRequest<I>::handle_remove_feature_bit(int r) { | |
136 | CephContext *cct = m_image_ctx.cct; | |
137 | ldout(cct, 10) << dendl; | |
138 | ||
139 | if (r < 0) { | |
140 | lderr(cct) << "failed to remove the feature bit: " << cpp_strerror(r) | |
141 | << dendl; | |
142 | save_result(r); | |
143 | } | |
144 | finish(); | |
145 | } | |
146 | ||
147 | template <typename I> | |
148 | void DiscardRequest<I>::finish() { | |
149 | if (m_cache_state) { | |
150 | delete m_cache_state; | |
151 | m_cache_state = nullptr; | |
152 | } | |
153 | ||
154 | m_on_finish->complete(m_error_result); | |
155 | delete this; | |
156 | } | |
157 | ||
158 | } // namespace pwl | |
159 | } // namespace cache | |
160 | } // namespace librbd | |
161 | ||
162 | template class librbd::cache::pwl::DiscardRequest<librbd::ImageCtx>; |