]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: don't resend async_complete if watcher is unregistered
authorMykola Golub <mgolub@suse.com>
Wed, 8 Jul 2020 15:04:12 +0000 (16:04 +0100)
committerMykola Golub <mgolub@suse.com>
Tue, 8 Sep 2020 07:49:11 +0000 (10:49 +0300)
Also wait for pending async_complete after unregistering the
watcher.

Fixes: https://tracker.ceph.com/issues/45268
Signed-off-by: Mykola Golub <mgolub@suse.com>
(cherry picked from commit 5b6804e19a8f524ab1528a638eb286482e12fe48)

Conflicts:
src/librbd/ImageWatcher.cc: FunctionContext vs LambdaContext
src/librbd/ImageWatcher.h: headers

src/librbd/ImageWatcher.cc
src/librbd/ImageWatcher.h

index f73a782dd60415f27fd677597f3e47a7c51d366e..c504df2f55a8af25f29eddc02ec79b8ce85b20f0 100644 (file)
@@ -86,6 +86,9 @@ void ImageWatcher<I>::unregister_watch(Context *on_finish) {
 
   cancel_async_requests();
 
+  on_finish = new FunctionContext([this, on_finish](int r) {
+    m_async_op_tracker.wait_for_ops(on_finish);
+  });
   FunctionContext *ctx = new FunctionContext([this, on_finish](int r) {
     m_task_finisher->cancel_all(on_finish);
   });
@@ -127,6 +130,7 @@ int ImageWatcher<I>::notify_async_progress(const AsyncRequestId &request,
 template <typename I>
 void ImageWatcher<I>::schedule_async_complete(const AsyncRequestId &request,
                                               int r) {
+  m_async_op_tracker.start_op();
   FunctionContext *ctx = new FunctionContext(
     boost::bind(&ImageWatcher<I>::notify_async_complete, this, request, r));
   m_task_finisher->queue(ctx);
@@ -152,13 +156,15 @@ void ImageWatcher<I>::handle_async_complete(const AsyncRequestId &request,
   if (ret_val < 0) {
     lderr(m_image_ctx.cct) << this << " failed to notify async complete: "
                           << cpp_strerror(ret_val) << dendl;
-    if (ret_val == -ETIMEDOUT) {
+    if (ret_val == -ETIMEDOUT && !is_unregistered()) {
       schedule_async_complete(request, r);
     }
   } else {
     RWLock::WLocker async_request_locker(m_async_request_lock);
     m_async_pending.erase(request);
   }
+
+  m_async_op_tracker.finish_op();
 }
 
 template <typename I>
index 441a7d696ad3e1b61212f2cc84b4721416f92cf8..7d04f0b4abda35a327e845e69a465af19431185a 100644 (file)
@@ -7,6 +7,7 @@
 #include "cls/rbd/cls_rbd_types.h"
 #include "common/Mutex.h"
 #include "common/RWLock.h"
+#include "common/AsyncOpTracker.h"
 #include "include/Context.h"
 #include "include/rbd/librbd.hpp"
 #include "librbd/Watcher.h"
@@ -172,6 +173,8 @@ private:
   Mutex m_owner_client_id_lock;
   watch_notify::ClientId m_owner_client_id;
 
+  AsyncOpTracker m_async_op_tracker;
+
   void handle_register_watch(int r);
 
   void schedule_cancel_async_requests();