]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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/watcher/RewatchRequest.h" | |
5 | #include "common/RWLock.h" | |
6 | #include "common/errno.h" | |
7 | #include "librbd/Utils.h" | |
8 | ||
9 | #define dout_subsys ceph_subsys_rbd | |
10 | #undef dout_prefix | |
11 | #define dout_prefix *_dout << "librbd::watcher::RewatchRequest: " \ | |
12 | << this << " " << __func__ << " " | |
13 | ||
14 | namespace librbd { | |
15 | ||
16 | using util::create_context_callback; | |
17 | using util::create_rados_callback; | |
18 | ||
19 | namespace watcher { | |
20 | ||
21 | using std::string; | |
22 | ||
23 | RewatchRequest::RewatchRequest(librados::IoCtx& ioctx, const string& oid, | |
24 | RWLock &watch_lock, | |
25 | librados::WatchCtx2 *watch_ctx, | |
26 | uint64_t *watch_handle, Context *on_finish) | |
27 | : m_ioctx(ioctx), m_oid(oid), m_watch_lock(watch_lock), | |
28 | m_watch_ctx(watch_ctx), m_watch_handle(watch_handle), | |
29 | m_on_finish(on_finish) { | |
30 | } | |
31 | ||
32 | void RewatchRequest::send() { | |
33 | unwatch(); | |
34 | } | |
35 | ||
36 | void RewatchRequest::unwatch() { | |
91327a77 AA |
37 | ceph_assert(m_watch_lock.is_wlocked()); |
38 | if (*m_watch_handle == 0) { | |
39 | rewatch(); | |
40 | return; | |
41 | } | |
7c673cae FG |
42 | |
43 | CephContext *cct = reinterpret_cast<CephContext *>(m_ioctx.cct()); | |
44 | ldout(cct, 10) << dendl; | |
45 | ||
91327a77 AA |
46 | uint64_t watch_handle = 0; |
47 | std::swap(*m_watch_handle, watch_handle); | |
48 | ||
7c673cae FG |
49 | librados::AioCompletion *aio_comp = create_rados_callback< |
50 | RewatchRequest, &RewatchRequest::handle_unwatch>(this); | |
91327a77 | 51 | int r = m_ioctx.aio_unwatch(watch_handle, aio_comp); |
11fdf7f2 | 52 | ceph_assert(r == 0); |
7c673cae | 53 | aio_comp->release(); |
7c673cae FG |
54 | } |
55 | ||
56 | void RewatchRequest::handle_unwatch(int r) { | |
57 | CephContext *cct = reinterpret_cast<CephContext *>(m_ioctx.cct()); | |
58 | ldout(cct, 10) << "r=" << r << dendl; | |
59 | ||
60 | if (r == -EBLACKLISTED) { | |
61 | lderr(cct) << "client blacklisted" << dendl; | |
62 | finish(r); | |
63 | return; | |
64 | } else if (r < 0) { | |
65 | lderr(cct) << "failed to unwatch: " << cpp_strerror(r) << dendl; | |
66 | } | |
67 | rewatch(); | |
68 | } | |
69 | ||
70 | void RewatchRequest::rewatch() { | |
71 | CephContext *cct = reinterpret_cast<CephContext *>(m_ioctx.cct()); | |
72 | ldout(cct, 10) << dendl; | |
73 | ||
74 | librados::AioCompletion *aio_comp = create_rados_callback< | |
75 | RewatchRequest, &RewatchRequest::handle_rewatch>(this); | |
76 | int r = m_ioctx.aio_watch(m_oid, aio_comp, &m_rewatch_handle, m_watch_ctx); | |
11fdf7f2 | 77 | ceph_assert(r == 0); |
7c673cae FG |
78 | aio_comp->release(); |
79 | } | |
80 | ||
81 | void RewatchRequest::handle_rewatch(int r) { | |
82 | CephContext *cct = reinterpret_cast<CephContext *>(m_ioctx.cct()); | |
83 | ldout(cct, 10) << "r=" << r << dendl; | |
91327a77 | 84 | if (r < 0) { |
7c673cae FG |
85 | lderr(cct) << "failed to watch object: " << cpp_strerror(r) |
86 | << dendl; | |
91327a77 | 87 | m_rewatch_handle = 0; |
7c673cae FG |
88 | } |
89 | ||
90 | { | |
91 | RWLock::WLocker watch_locker(m_watch_lock); | |
92 | *m_watch_handle = m_rewatch_handle; | |
93 | } | |
94 | ||
91327a77 | 95 | finish(r); |
7c673cae FG |
96 | } |
97 | ||
98 | void RewatchRequest::finish(int r) { | |
99 | CephContext *cct = reinterpret_cast<CephContext *>(m_ioctx.cct()); | |
100 | ldout(cct, 10) << "r=" << r << dendl; | |
101 | ||
102 | m_on_finish->complete(r); | |
103 | delete this; | |
104 | } | |
105 | ||
106 | } // namespace watcher | |
107 | } // namespace librbd | |
108 |