From: Song Shun Date: Tue, 10 Apr 2018 05:41:18 +0000 (+0800) Subject: librbd: fix rbd close race with rewatch X-Git-Tag: v13.1.0~231^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=8b833a293eac54fd3d38f12660d856ecc310d805;p=ceph.git librbd: fix rbd close race with rewatch fix rbd close race with rewatch Signed-off-by: Song Shun --- diff --git a/src/librbd/Watcher.cc b/src/librbd/Watcher.cc index 37fdaaebed6d..9c3ef192745e 100644 --- a/src/librbd/Watcher.cc +++ b/src/librbd/Watcher.cc @@ -250,13 +250,22 @@ void Watcher::rewatch() { } void Watcher::handle_rewatch(int r) { - ldout(m_cct, 10) "r=" << r << dendl; + ldout(m_cct, 10) << "r=" << r << dendl; WatchState next_watch_state = WATCH_STATE_REGISTERED; - if (r < 0) { - // only EBLACKLISTED or ENOENT can be returned - assert(r == -EBLACKLISTED || r == -ENOENT); + if (r == -EBLACKLISTED) { + lderr(m_cct) << "client blacklisted" << dendl; + next_watch_state = WATCH_STATE_UNREGISTERED; + } else if (r == -ENOENT) { + lderr(m_cct) << "failed to unwatch: " << cpp_strerror(r) << dendl; next_watch_state = WATCH_STATE_UNREGISTERED; + } else if (r < 0) { + next_watch_state = WATCH_STATE_ERROR; + if (m_unregister_watch_ctx != nullptr) { + ldout(m_cct, 10) << "image is closing, skip rewatch" << dendl; + } else { + rewatch(); + } } Context *unregister_watch_ctx = nullptr; diff --git a/src/librbd/watcher/RewatchRequest.cc b/src/librbd/watcher/RewatchRequest.cc index fe236269793a..22d2bb8e5678 100644 --- a/src/librbd/watcher/RewatchRequest.cc +++ b/src/librbd/watcher/RewatchRequest.cc @@ -78,19 +78,10 @@ void RewatchRequest::rewatch() { void RewatchRequest::handle_rewatch(int r) { CephContext *cct = reinterpret_cast(m_ioctx.cct()); ldout(cct, 10) << "r=" << r << dendl; - - if (r == -EBLACKLISTED) { - lderr(cct) << "client blacklisted" << dendl; - finish(r); - return; - } else if (r == -ENOENT) { - ldout(cct, 5) << "object deleted" << dendl; - finish(r); - return; - } else if (r < 0) { + if (r < 0) { lderr(cct) << "failed to watch object: " << cpp_strerror(r) << dendl; - rewatch(); + finish(r); return; } diff --git a/src/test/librbd/watcher/test_mock_RewatchRequest.cc b/src/test/librbd/watcher/test_mock_RewatchRequest.cc index 33945e24ed45..cd4dd297765b 100644 --- a/src/test/librbd/watcher/test_mock_RewatchRequest.cc +++ b/src/test/librbd/watcher/test_mock_RewatchRequest.cc @@ -176,7 +176,6 @@ TEST_F(TestMockWatcherRewatchRequest, WatchError) { InSequence seq; expect_aio_unwatch(mock_image_ctx, 0); expect_aio_watch(mock_image_ctx, -EINVAL); - expect_aio_watch(mock_image_ctx, 0); C_SaferCond ctx; MockRewatchRequest *req = MockRewatchRequest::create(mock_image_ctx.md_ctx, @@ -189,7 +188,7 @@ TEST_F(TestMockWatcherRewatchRequest, WatchError) { RWLock::WLocker watch_locker(m_watch_lock); req->send(); } - ASSERT_EQ(0, ctx.wait()); + ASSERT_EQ(-EINVAL, ctx.wait()); } } // namespace watcher