From 92a42561f88548ffe03f9c25e07ac5002748df7c Mon Sep 17 00:00:00 2001 From: Jason Dillaman Date: Fri, 20 Mar 2015 10:40:22 -0400 Subject: [PATCH] librbd: update in-memory object map before on-disk update completes When multiple IO updates are occurring within the same object, this will allow only a single object map update request to be sent to the OSD. Signed-off-by: Jason Dillaman --- src/librbd/ObjectMap.cc | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/src/librbd/ObjectMap.cc b/src/librbd/ObjectMap.cc index aa30fac588444..4c9e2a73cdf4c 100644 --- a/src/librbd/ObjectMap.cc +++ b/src/librbd/ObjectMap.cc @@ -481,15 +481,27 @@ void ObjectMap::ResizeRequest::finish(ObjectMap *object_map) { } void ObjectMap::UpdateRequest::send() { + assert(m_image_ctx.object_map_lock.is_wlocked()); CephContext *cct = m_image_ctx.cct; - ldout(cct, 20) << &m_image_ctx << " updating on-disk object map: [" + // safe to update in-memory state first without handling rollback since any + // failures will invalidate the object map + ldout(cct, 20) << &m_image_ctx << " updating object map: [" << m_start_object_no << "," << m_end_object_no << ") = " << (m_current_state ? stringify(static_cast(*m_current_state)) : "") << "->" << static_cast(m_new_state) << dendl; - + ObjectMap& object_map = m_image_ctx.object_map; + for (uint64_t object_no = m_start_object_no; + object_no < MIN(m_end_object_no, object_map.m_object_map.size()); + ++object_no) { + if (!m_current_state || + object_map.m_object_map[object_no] == *m_current_state) { + object_map.m_object_map[object_no] = m_new_state; + } + } + librados::ObjectWriteOperation op; rados::cls::lock::assert_locked(&op, RBD_LOCK_NAME, LOCK_EXCLUSIVE, "", ""); cls_client::object_map_update(&op, m_start_object_no, m_end_object_no, @@ -503,17 +515,8 @@ void ObjectMap::UpdateRequest::send() { } void ObjectMap::UpdateRequest::finish(ObjectMap *object_map) { - CephContext *cct = m_image_ctx.cct; - - ldout(cct, 20) << &m_image_ctx << " updating in-memory object map" << dendl; - for (uint64_t object_no = m_start_object_no; - object_no < MIN(m_end_object_no, object_map->m_object_map.size()); - ++object_no) { - if (!m_current_state || - object_map->m_object_map[object_no] == *m_current_state) { - object_map->m_object_map[object_no] = m_new_state; - } - } + ldout(m_image_ctx.cct, 20) << &m_image_ctx << " on-disk object map updated" + << dendl; } } // namespace librbd -- 2.39.5