From: Jason Dillaman Date: Thu, 18 Jun 2020 19:20:40 +0000 (-0400) Subject: librbd: race when disabling object map with overlapping in-flight writes X-Git-Tag: wip-pdonnell-testing-20200918.022351~932^2 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=ee69323cd27263cb7f9dd97dcbfb1c36f1cc0837;p=ceph-ci.git librbd: race when disabling object map with overlapping in-flight writes 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 --- diff --git a/src/librbd/ObjectMap.cc b/src/librbd/ObjectMap.cc index b0922c909f3..8f998da1103 100644 --- a/src/librbd/ObjectMap.cc +++ b/src/librbd/ObjectMap.cc @@ -163,8 +163,14 @@ void ObjectMap::close(Context *on_finish) { return; } - auto req = object_map::UnlockRequest::create(m_image_ctx, ctx); - req->send(); + ctx = new LambdaContext([this, ctx](int r) { + auto req = object_map::UnlockRequest::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 @@ -276,6 +282,7 @@ void ObjectMap::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::handle_detained_aio_update(BlockGuardCell *cell, int r, } on_finish->complete(r); + m_async_op_tracker.finish_op(); } template diff --git a/src/librbd/ObjectMap.h b/src/librbd/ObjectMap.h index 9cadb329103..7577d267f44 100644 --- a/src/librbd/ObjectMap.h +++ b/src/librbd/ObjectMap.h @@ -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);