]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
librbd: race when disabling object map with overlapping in-flight writes
authorJason Dillaman <dillaman@redhat.com>
Thu, 18 Jun 2020 19:20:40 +0000 (15:20 -0400)
committerJason Dillaman <dillaman@redhat.com>
Sat, 20 Jun 2020 08:48:36 +0000 (04:48 -0400)
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>
src/librbd/ObjectMap.cc
src/librbd/ObjectMap.h

index b0922c909f3db5d3d012740890be67d76884d44c..8f998da11034c65efbeba01583522aad7e407ad8 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);