]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: race when disabling object map with overlapping in-flight writes 36656/head
authorJason Dillaman <dillaman@redhat.com>
Thu, 18 Jun 2020 19:20:40 +0000 (15:20 -0400)
committerNathan Cutler <ncutler@suse.com>
Sat, 15 Aug 2020 13:14:58 +0000 (15:14 +0200)
The block guard that protects against overlapping updates to the object
map needs to be flushed prior to closing the object map instance.

Fixes: https://tracker.ceph.com/issues/46083
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
(cherry picked from commit ee69323cd27263cb7f9dd97dcbfb1c36f1cc0837)

src/librbd/ObjectMap.cc
src/librbd/ObjectMap.h

index 0d60cc95f94e5790c012993c2e951a8b62c073f9..2913277396bfb325d8ded3c2063e4c26fcbec0c5 100644 (file)
@@ -163,8 +163,14 @@ void ObjectMap<I>::close(Context *on_finish) {
     return;
   }
 
-  auto req = object_map::UnlockRequest<I>::create(m_image_ctx, ctx);
-  req->send();
+  ctx = new LambdaContext([this, ctx](int r) {
+      auto req = object_map::UnlockRequest<I>::create(m_image_ctx, ctx);
+      req->send();
+    });
+
+  // ensure the block guard for aio updates is empty before unlocking
+  // the object map
+  m_async_op_tracker.wait_for_ops(ctx);
 }
 
 template <typename I>
@@ -276,6 +282,7 @@ void ObjectMap<I>::detained_aio_update(UpdateOperation &&op) {
     lderr(cct) << "failed to detain object map update: " << cpp_strerror(r)
                << dendl;
     m_image_ctx.op_work_queue->queue(op.on_finish, r);
+    m_async_op_tracker.finish_op();
     return;
   } else if (r > 0) {
     ldout(cct, 20) << "detaining object map update due to in-flight update: "
@@ -315,6 +322,7 @@ void ObjectMap<I>::handle_detained_aio_update(BlockGuardCell *cell, int r,
   }
 
   on_finish->complete(r);
+  m_async_op_tracker.finish_op();
 }
 
 template <typename I>
index 9cadb32910362ea9890e536b172b78f6e77e31f6..7577d267f44060c7c4f89eae2e64a4e9c8e940b4 100644 (file)
@@ -8,6 +8,7 @@
 #include "include/fs_types.h"
 #include "include/rados/librados_fwd.hpp"
 #include "include/rbd/object_map_types.h"
+#include "common/AsyncOpTracker.h"
 #include "common/bit_vector.hpp"
 #include "common/RWLock.h"
 #include "common/RefCountedObj.h"
@@ -102,6 +103,7 @@ public:
         return false;
       }
 
+      m_async_op_tracker.start_op();
       UpdateOperation update_operation(start_object_no, end_object_no,
                                        new_state, current_state, parent_trace,
                                        ignore_enoent,
@@ -150,6 +152,7 @@ private:
   mutable ceph::shared_mutex m_lock;
   ceph::BitVector<2> m_object_map;
 
+  AsyncOpTracker m_async_op_tracker;
   UpdateGuard *m_update_guard = nullptr;
 
   void detained_aio_update(UpdateOperation &&update_operation);