]>
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() { | |
37 | assert(m_watch_lock.is_wlocked()); | |
91327a77 AA |
38 | ceph_assert(m_watch_lock.is_wlocked()); |
39 | if (*m_watch_handle == 0) { | |
40 | rewatch(); | |
41 | return; | |
42 | } | |
7c673cae FG |
43 | |
44 | CephContext *cct = reinterpret_cast<CephContext *>(m_ioctx.cct()); | |
45 | ldout(cct, 10) << dendl; | |
46 | ||
91327a77 AA |
47 | uint64_t watch_handle = 0; |
48 | std::swap(*m_watch_handle, watch_handle); | |
49 | ||
7c673cae FG |
50 | librados::AioCompletion *aio_comp = create_rados_callback< |
51 | RewatchRequest, &RewatchRequest::handle_unwatch>(this); | |
91327a77 | 52 | int r = m_ioctx.aio_unwatch(watch_handle, aio_comp); |
7c673cae FG |
53 | assert(r == 0); |
54 | aio_comp->release(); | |
7c673cae FG |
55 | } |
56 | ||
57 | void RewatchRequest::handle_unwatch(int r) { | |
58 | CephContext *cct = reinterpret_cast<CephContext *>(m_ioctx.cct()); | |
59 | ldout(cct, 10) << "r=" << r << dendl; | |
60 | ||
61 | if (r == -EBLACKLISTED) { | |
62 | lderr(cct) << "client blacklisted" << dendl; | |
63 | finish(r); | |
64 | return; | |
65 | } else if (r < 0) { | |
66 | lderr(cct) << "failed to unwatch: " << cpp_strerror(r) << dendl; | |
67 | } | |
68 | rewatch(); | |
69 | } | |
70 | ||
71 | void RewatchRequest::rewatch() { | |
72 | CephContext *cct = reinterpret_cast<CephContext *>(m_ioctx.cct()); | |
73 | ldout(cct, 10) << dendl; | |
74 | ||
75 | librados::AioCompletion *aio_comp = create_rados_callback< | |
76 | RewatchRequest, &RewatchRequest::handle_rewatch>(this); | |
77 | int r = m_ioctx.aio_watch(m_oid, aio_comp, &m_rewatch_handle, m_watch_ctx); | |
78 | assert(r == 0); | |
79 | aio_comp->release(); | |
80 | } | |
81 | ||
82 | void RewatchRequest::handle_rewatch(int r) { | |
83 | CephContext *cct = reinterpret_cast<CephContext *>(m_ioctx.cct()); | |
84 | ldout(cct, 10) << "r=" << r << dendl; | |
91327a77 | 85 | if (r < 0) { |
7c673cae FG |
86 | lderr(cct) << "failed to watch object: " << cpp_strerror(r) |
87 | << dendl; | |
91327a77 | 88 | m_rewatch_handle = 0; |
7c673cae FG |
89 | } |
90 | ||
91 | { | |
92 | RWLock::WLocker watch_locker(m_watch_lock); | |
93 | *m_watch_handle = m_rewatch_handle; | |
94 | } | |
95 | ||
91327a77 | 96 | finish(r); |
7c673cae FG |
97 | } |
98 | ||
99 | void RewatchRequest::finish(int r) { | |
100 | CephContext *cct = reinterpret_cast<CephContext *>(m_ioctx.cct()); | |
101 | ldout(cct, 10) << "r=" << r << dendl; | |
102 | ||
103 | m_on_finish->complete(r); | |
104 | delete this; | |
105 | } | |
106 | ||
107 | } // namespace watcher | |
108 | } // namespace librbd | |
109 |