]>
Commit | Line | Data |
---|---|---|
11fdf7f2 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/trash/MoveRequest.h" | |
5 | #include "common/dout.h" | |
6 | #include "common/errno.h" | |
7 | #include "cls/rbd/cls_rbd_client.h" | |
11fdf7f2 TL |
8 | #include "librbd/ImageCtx.h" |
9 | #include "librbd/ImageState.h" | |
10 | #include "librbd/Utils.h" | |
11 | ||
12 | #define dout_subsys ceph_subsys_rbd | |
13 | #undef dout_prefix | |
14 | #define dout_prefix *_dout << "librbd::trash::MoveRequest: " << this \ | |
15 | << " " << __func__ << ": " | |
16 | ||
17 | namespace librbd { | |
18 | namespace trash { | |
19 | ||
20 | using util::create_context_callback; | |
21 | using util::create_rados_callback; | |
22 | ||
23 | template <typename I> | |
24 | void MoveRequest<I>::send() { | |
25 | trash_add(); | |
26 | } | |
27 | ||
28 | template <typename I> | |
29 | void MoveRequest<I>::trash_add() { | |
30 | ldout(m_cct, 10) << dendl; | |
31 | ||
32 | librados::ObjectWriteOperation op; | |
33 | librbd::cls_client::trash_add(&op, m_image_id, m_trash_image_spec); | |
34 | ||
35 | auto aio_comp = create_rados_callback< | |
36 | MoveRequest<I>, &MoveRequest<I>::handle_trash_add>(this); | |
37 | int r = m_io_ctx.aio_operate(RBD_TRASH, aio_comp, &op); | |
38 | ceph_assert(r == 0); | |
39 | aio_comp->release(); | |
40 | } | |
41 | ||
42 | template <typename I> | |
43 | void MoveRequest<I>::handle_trash_add(int r) { | |
44 | ldout(m_cct, 10) << "r=" << r << dendl; | |
45 | ||
46 | if (r == -EEXIST) { | |
47 | ldout(m_cct, 10) << "previous unfinished deferred remove for image: " | |
48 | << m_image_id << dendl; | |
49 | } else if (r < 0) { | |
50 | lderr(m_cct) << "failed to add image to trash: " << cpp_strerror(r) | |
51 | << dendl; | |
52 | finish(r); | |
53 | return; | |
54 | } | |
55 | ||
56 | remove_id(); | |
57 | } | |
58 | ||
59 | template <typename I> | |
60 | void MoveRequest<I>::remove_id() { | |
61 | ldout(m_cct, 10) << dendl; | |
62 | ||
63 | auto aio_comp = create_rados_callback< | |
64 | MoveRequest<I>, &MoveRequest<I>::handle_remove_id>(this); | |
65 | int r = m_io_ctx.aio_remove(util::id_obj_name(m_trash_image_spec.name), | |
66 | aio_comp); | |
67 | ceph_assert(r == 0); | |
68 | aio_comp->release(); | |
69 | } | |
70 | ||
71 | template <typename I> | |
72 | void MoveRequest<I>::handle_remove_id(int r) { | |
73 | ldout(m_cct, 10) << "r=" << r << dendl; | |
74 | ||
75 | if (r < 0 && r != -ENOENT) { | |
76 | lderr(m_cct) << "failed to remove image id object: " << cpp_strerror(r) | |
77 | << dendl; | |
78 | finish(r); | |
79 | return; | |
80 | } | |
81 | ||
82 | directory_remove(); | |
83 | } | |
84 | ||
85 | template <typename I> | |
86 | void MoveRequest<I>::directory_remove() { | |
87 | ldout(m_cct, 10) << dendl; | |
88 | ||
89 | librados::ObjectWriteOperation op; | |
90 | librbd::cls_client::dir_remove_image(&op, m_trash_image_spec.name, | |
91 | m_image_id); | |
92 | ||
93 | auto aio_comp = create_rados_callback< | |
94 | MoveRequest<I>, &MoveRequest<I>::handle_directory_remove>(this); | |
95 | int r = m_io_ctx.aio_operate(RBD_DIRECTORY, aio_comp, &op); | |
96 | ceph_assert(r == 0); | |
97 | aio_comp->release(); | |
98 | } | |
99 | ||
100 | template <typename I> | |
101 | void MoveRequest<I>::handle_directory_remove(int r) { | |
102 | ldout(m_cct, 10) << "r=" << r << dendl; | |
103 | ||
104 | if (r < 0 && r != -ENOENT) { | |
105 | lderr(m_cct) << "failed to remove image from directory: " << cpp_strerror(r) | |
106 | << dendl; | |
107 | } | |
108 | ||
109 | finish(r); | |
110 | } | |
111 | ||
112 | template <typename I> | |
113 | void MoveRequest<I>::finish(int r) { | |
114 | ldout(m_cct, 10) << "r=" << r << dendl; | |
115 | ||
116 | m_on_finish->complete(r); | |
117 | delete this; | |
118 | } | |
119 | ||
120 | } // namespace trash | |
121 | } // namespace librbd | |
122 | ||
123 | template class librbd::trash::MoveRequest<librbd::ImageCtx>; |