]> git.proxmox.com Git - ceph.git/blame - ceph/src/librbd/cache/pwl/DiscardRequest.cc
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / librbd / cache / pwl / DiscardRequest.cc
CommitLineData
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>
12namespace fs = std::filesystem;
13#elif __has_include(<experimental/filesystem>)
14#include <experimental/filesystem>
15namespace 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
31namespace librbd {
32namespace cache {
33namespace pwl {
34
35using librbd::util::create_async_context_callback;
36using librbd::util::create_context_callback;
37
38template <typename I>
39DiscardRequest<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
46template <typename I>
47DiscardRequest<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
57template <typename I>
58void DiscardRequest<I>::send() {
59 delete_image_cache_file();
60}
61
62template <typename I>
63void 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
81template <typename I>
82void 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
93template <typename I>
94void 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
109template <typename I>
110void 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
134template <typename I>
135void 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
147template <typename I>
148void 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
162template class librbd::cache::pwl::DiscardRequest<librbd::ImageCtx>;