]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: object map is not properly updated when deleting clean objects 4530/head
authorJason Dillaman <dillaman@redhat.com>
Fri, 1 May 2015 18:41:40 +0000 (14:41 -0400)
committerJason Dillaman <dillaman@redhat.com>
Fri, 1 May 2015 19:07:40 +0000 (15:07 -0400)
With the new fast diff feature flagging which objects haven't changed
between snapshots, unmodified objects are now flagged with a new state
code in the object map.  The OBJECT_EXISTS_CLEAN state needs to be
treated as if it were OBJECT_EXISTS when deleting.

Signed-off-by: Jason Dillaman <dillaman@redhat.com>
src/cls/rbd/cls_rbd.cc
src/librbd/ObjectMap.cc

index 281f566f9da057aae9df41fc09c71cd3be7edddd..0cf5eb84d7a7a0ce88867f54c980aa9e97ae2420 100644 (file)
@@ -2211,8 +2211,10 @@ int object_map_update(cls_method_context_t hctx, bufferlist *in, bufferlist *out
   bool updated = false;
   for (uint64_t object_no = start_object_no; object_no < end_object_no;
        ++object_no) {
-    if ((!current_object_state || object_map[object_no] == *current_object_state) &&
-       object_map[object_no] != new_object_state) {
+    uint8_t state = object_map[object_no];
+    if ((!current_object_state || state == *current_object_state ||
+        (*current_object_state == OBJECT_EXISTS &&
+         state == OBJECT_EXISTS_CLEAN)) && state != new_object_state) {
       object_map[object_no] = new_object_state;
       updated = true;
     }
index 1b158da93bcad04347a42be2558d12649e8fe990..48ae1f552b89c786a69f1137b142db502c283746 100644 (file)
@@ -459,8 +459,10 @@ bool ObjectMap::aio_update(uint64_t start_object_no, uint64_t end_object_no,
 
   CephContext *cct = m_image_ctx.cct;
   ldout(cct, 20) << &m_image_ctx << " aio_update: start=" << start_object_no
-                << ", end=" << end_object_no << ", new_state="
-                << static_cast<uint32_t>(new_state) << dendl;
+                << ", end=" << end_object_no << ", "
+                 << (current_state ?
+                       stringify(static_cast<uint32_t>(*current_state)) : "")
+                << "->" << static_cast<uint32_t>(new_state) << dendl;
   if (end_object_no > m_object_map.size()) {
     ldout(cct, 20) << "skipping update of invalid object map" << dendl;
     return false;
@@ -468,8 +470,10 @@ bool ObjectMap::aio_update(uint64_t start_object_no, uint64_t end_object_no,
 
   for (uint64_t object_no = start_object_no; object_no < end_object_no;
        ++object_no) {
-    if ((!current_state || m_object_map[object_no] == *current_state) &&
-        m_object_map[object_no] != new_state) {
+    uint8_t state = m_object_map[object_no];
+    if ((!current_state || state == *current_state ||
+          (*current_state == OBJECT_EXISTS && state == OBJECT_EXISTS_CLEAN)) &&
+        state != new_state) {
       UpdateRequest *req = new UpdateRequest(m_image_ctx, m_snap_id,
                                              start_object_no, end_object_no,
                                              new_state, current_state,
@@ -638,8 +642,9 @@ void ObjectMap::UpdateRequest::send() {
   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) {
+    uint8_t state = object_map.m_object_map[object_no];
+    if (!m_current_state || state == *m_current_state ||
+          (*m_current_state == OBJECT_EXISTS && state == OBJECT_EXISTS_CLEAN)) {
       object_map.m_object_map[object_no] = m_new_state;
     }
   }