1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #include "librbd/trash/RemoveRequest.h"
5 #include "common/WorkQueue.h"
6 #include "common/dout.h"
7 #include "common/errno.h"
8 #include "cls/rbd/cls_rbd_client.h"
9 #include "librbd/ExclusiveLock.h"
10 #include "librbd/ImageCtx.h"
11 #include "librbd/ImageState.h"
12 #include "librbd/Utils.h"
13 #include "librbd/image/RemoveRequest.h"
15 #define dout_subsys ceph_subsys_rbd
17 #define dout_prefix *_dout << "librbd::trash::RemoveRequest: " << this \
18 << " " << __func__ << ": "
23 using util::create_context_callback
;
24 using util::create_rados_callback
;
27 void RemoveRequest
<I
>::send() {
32 void RemoveRequest
<I
>::set_state() {
33 ldout(m_cct
, 10) << dendl
;
35 librados::ObjectWriteOperation op
;
36 cls_client::trash_state_set(&op
, m_image_id
, m_trash_set_state
,
37 m_trash_expect_state
);
39 auto aio_comp
= create_rados_callback
<
40 RemoveRequest
<I
>, &RemoveRequest
<I
>::handle_set_state
>(this);
41 int r
= m_io_ctx
.aio_operate(RBD_TRASH
, aio_comp
, &op
);
47 void RemoveRequest
<I
>::handle_set_state(int r
) {
48 ldout(m_cct
, 10) << "r=" << r
<< dendl
;
50 if (r
< 0 && r
!= -EOPNOTSUPP
) {
51 lderr(m_cct
) << "error setting trash image state: " << cpp_strerror(r
)
56 if (m_trash_set_state
== cls::rbd::TRASH_IMAGE_STATE_REMOVING
) {
64 if (m_trash_set_state
== cls::rbd::TRASH_IMAGE_STATE_REMOVING
) {
67 ceph_assert(m_trash_set_state
== cls::rbd::TRASH_IMAGE_STATE_NORMAL
);
68 finish(m_ret_val
< 0 ? m_ret_val
: r
);
73 void RemoveRequest
<I
>::close_image() {
74 if (m_image_ctx
== nullptr) {
79 ldout(m_cct
, 10) << dendl
;
81 auto ctx
= create_context_callback
<
82 RemoveRequest
<I
>, &RemoveRequest
<I
>::handle_close_image
>(this);
83 m_image_ctx
->state
->close(ctx
);
87 void RemoveRequest
<I
>::handle_close_image(int r
) {
88 ldout(m_cct
, 10) << "r=" << r
<< dendl
;
91 ldout(m_cct
, 5) << "failed to close image:" << cpp_strerror(r
) << dendl
;
94 m_image_ctx
->destroy();
95 m_image_ctx
= nullptr;
100 void RemoveRequest
<I
>::remove_image() {
101 ldout(m_cct
, 10) << dendl
;
103 auto ctx
= create_context_callback
<
104 RemoveRequest
<I
>, &RemoveRequest
<I
>::handle_remove_image
>(this);
105 if (m_image_ctx
!= nullptr) {
106 auto req
= librbd::image::RemoveRequest
<I
>::create(
107 m_io_ctx
, m_image_ctx
, m_force
, true, m_prog_ctx
, m_op_work_queue
, ctx
);
110 auto req
= librbd::image::RemoveRequest
<I
>::create(
111 m_io_ctx
, "", m_image_id
, m_force
, true, m_prog_ctx
, m_op_work_queue
,
117 template <typename I
>
118 void RemoveRequest
<I
>::handle_remove_image(int r
) {
119 ldout(m_cct
, 10) << "r=" << r
<< dendl
;
122 ldout(m_cct
, 5) << "failed to remove image:" << cpp_strerror(r
) << dendl
;
125 m_trash_set_state
= cls::rbd::TRASH_IMAGE_STATE_NORMAL
;
126 m_trash_expect_state
= cls::rbd::TRASH_IMAGE_STATE_REMOVING
;
131 m_image_ctx
= nullptr;
132 remove_trash_entry();
135 template <typename I
>
136 void RemoveRequest
<I
>::remove_trash_entry() {
137 ldout(m_cct
, 10) << dendl
;
139 librados::ObjectWriteOperation op
;
140 cls_client::trash_remove(&op
, m_image_id
);
142 auto aio_comp
= create_rados_callback
<
143 RemoveRequest
<I
>, &RemoveRequest
<I
>::handle_remove_trash_entry
>(this);
144 int r
= m_io_ctx
.aio_operate(RBD_TRASH
, aio_comp
, &op
);
149 template <typename I
>
150 void RemoveRequest
<I
>::handle_remove_trash_entry(int r
) {
151 ldout(m_cct
, 10) << "r=" << r
<< dendl
;
153 if (r
< 0 && r
!= -ENOENT
) {
154 lderr(m_cct
) << "error removing trash entry: " << cpp_strerror(r
) << dendl
;
160 template <typename I
>
161 void RemoveRequest
<I
>::finish(int r
) {
162 ldout(m_cct
, 10) << "r=" << r
<< dendl
;
164 m_on_finish
->complete(r
);
169 } // namespace librbd
171 template class librbd::trash::RemoveRequest
<librbd::ImageCtx
>;