From 65ef695eba0f5b5d87347ffb3407bb5d6d75b402 Mon Sep 17 00:00:00 2001 From: Jason Dillaman Date: Thu, 19 Mar 2015 15:35:59 -0400 Subject: [PATCH] librbd: require callers to ObjectMap::aio_update to acquire lock This is needed to allow an atomic compare and update operation from the rebuild object map utility. Signed-off-by: Jason Dillaman (cherry picked from commit 2db758cb4cb6d88cbaf9842b1e5d0872a185d8df) --- src/librbd/AioRequest.cc | 2 ++ src/librbd/AsyncTrimRequest.cc | 2 ++ src/librbd/CopyupRequest.cc | 1 + src/librbd/ObjectMap.cc | 4 +--- 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/librbd/AioRequest.cc b/src/librbd/AioRequest.cc index d52cd5da8ee2e..33908a4dfaaa9 100644 --- a/src/librbd/AioRequest.cc +++ b/src/librbd/AioRequest.cc @@ -467,6 +467,7 @@ namespace librbd { m_state = LIBRBD_AIO_WRITE_PRE; FunctionContext *ctx = new FunctionContext( boost::bind(&AioRequest::complete, this, _1)); + RWLock::WLocker object_map_locker(m_ictx->object_map_lock); if (!m_ictx->object_map.aio_update(m_object_no, new_state, current_state, ctx)) { // no object map update required @@ -501,6 +502,7 @@ namespace librbd { m_state = LIBRBD_AIO_WRITE_POST; FunctionContext *ctx = new FunctionContext( boost::bind(&AioRequest::complete, this, _1)); + RWLock::WLocker object_map_locker(m_ictx->object_map_lock); if (!m_ictx->object_map.aio_update(m_object_no, OBJECT_NONEXISTENT, OBJECT_PENDING, ctx)) { // no object map update required diff --git a/src/librbd/AsyncTrimRequest.cc b/src/librbd/AsyncTrimRequest.cc index cb4764a22fd97..af325f612f57f 100644 --- a/src/librbd/AsyncTrimRequest.cc +++ b/src/librbd/AsyncTrimRequest.cc @@ -173,6 +173,7 @@ void AsyncTrimRequest::send_pre_remove() { } else { // flag the objects as pending deletion Context *ctx = create_callback_context(); + RWLock::WLocker object_map_locker(m_image_ctx.object_map_lock); if (!m_image_ctx.object_map.aio_update(m_delete_start, m_num_objects, OBJECT_PENDING, OBJECT_EXISTS, ctx)) { @@ -210,6 +211,7 @@ bool AsyncTrimRequest::send_post_remove() { } else { // flag the pending objects as removed Context *ctx = create_callback_context(); + RWLock::WLocker object_map_locker(m_image_ctx.object_map_lock); if (!m_image_ctx.object_map.aio_update(m_delete_start, m_num_objects, OBJECT_NONEXISTENT, OBJECT_PENDING, ctx)) { diff --git a/src/librbd/CopyupRequest.cc b/src/librbd/CopyupRequest.cc index 3d780c6cc1b63..2f56c49ae0116 100644 --- a/src/librbd/CopyupRequest.cc +++ b/src/librbd/CopyupRequest.cc @@ -179,6 +179,7 @@ namespace librbd { } else { m_state = STATE_OBJECT_MAP; Context *ctx = create_callback_context(); + RWLock::WLocker object_map_locker(m_ictx->object_map_lock); if (!m_ictx->object_map.aio_update(m_object_no, OBJECT_EXISTS, boost::optional(), ctx)) { delete ctx; diff --git a/src/librbd/ObjectMap.cc b/src/librbd/ObjectMap.cc index c2ca798b584ff..9da30cc2e0852 100644 --- a/src/librbd/ObjectMap.cc +++ b/src/librbd/ObjectMap.cc @@ -299,9 +299,7 @@ bool ObjectMap::aio_update(uint64_t start_object_no, uint64_t end_object_no, assert(m_image_ctx.owner_lock.is_locked()); assert(m_image_ctx.image_watcher != NULL); assert(m_image_ctx.image_watcher->is_lock_owner()); - assert(start_object_no < end_object_no); - - RWLock::WLocker l(m_image_ctx.object_map_lock); + assert(m_image_ctx.object_map_lock.is_wlocked()); assert(start_object_no < end_object_no); CephContext *cct = m_image_ctx.cct; -- 2.39.5