From: Jason Dillaman Date: Fri, 20 Mar 2015 14:40:22 +0000 (-0400) Subject: librbd: update in-memory object map before on-disk update completes X-Git-Tag: v9.0.1~149^2~9 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=92a42561f88548ffe03f9c25e07ac5002748df7c;p=ceph.git 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 --- diff --git a/src/librbd/ObjectMap.cc b/src/librbd/ObjectMap.cc index aa30fac58844..4c9e2a73cdf4 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