From a6f16f5c7ecfa43d1aa42073a12a2d19e6c52fb5 Mon Sep 17 00:00:00 2001 From: Jason Dillaman Date: Thu, 18 Jun 2020 15:20:40 -0400 Subject: [PATCH] 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 (cherry picked from commit ee69323cd27263cb7f9dd97dcbfb1c36f1cc0837) Conflicts: src/librbd/ObjectMap.cc (FunctionContext vs LambdaContext, on_finish vs ctx) --- src/librbd/ObjectMap.cc | 12 ++++++++++-- src/librbd/ObjectMap.h | 3 +++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/librbd/ObjectMap.cc b/src/librbd/ObjectMap.cc index 50cbfda89220e..7e73d7f3ce521 100644 --- a/src/librbd/ObjectMap.cc +++ b/src/librbd/ObjectMap.cc @@ -165,8 +165,14 @@ void ObjectMap::close(Context *on_finish) { return; } - auto req = object_map::UnlockRequest::create(m_image_ctx, on_finish); - req->send(); + auto ctx = new FunctionContext([this, on_finish](int r) { + auto req = object_map::UnlockRequest::create(m_image_ctx, on_finish); + 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 @@ -268,6 +274,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: " @@ -307,6 +314,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 c930a5b554a35..0991416dc5300 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 "librbd/Utils.h" #include @@ -89,6 +90,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, @@ -135,6 +137,7 @@ private: ceph::BitVector<2> m_object_map; uint64_t m_snap_id; + AsyncOpTracker m_async_op_tracker; UpdateGuard *m_update_guard = nullptr; void detained_aio_update(UpdateOperation &&update_operation); -- 2.39.5