]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: update in-memory object map before on-disk update completes
authorJason Dillaman <dillaman@redhat.com>
Fri, 20 Mar 2015 14:40:22 +0000 (10:40 -0400)
committerJason Dillaman <dillaman@redhat.com>
Fri, 10 Apr 2015 18:10:05 +0000 (14:10 -0400)
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 <dillaman@redhat.com>
src/librbd/ObjectMap.cc

index aa30fac5884440e5c0d1658f18b650d86a851b7b..4c9e2a73cdf4c2a2b1233e8631f7eaee75ef9073 100644 (file)
@@ -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<uint32_t>(*m_current_state)) : "")
                 << "->" << static_cast<uint32_t>(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