]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: diff iterate with fast-diff now correctly includes parent 32403/head
authorJason Dillaman <dillaman@redhat.com>
Mon, 23 Dec 2019 16:34:07 +0000 (11:34 -0500)
committerJason Dillaman <dillaman@redhat.com>
Mon, 23 Dec 2019 16:34:07 +0000 (11:34 -0500)
When whole-object and include-parent options are enabled, the
diff will now include the parent image diffs. Previously, the
parent image diffs were not included when fast-diff was enabled
but was included when fast-diff was disabled.

Fixes: https://tracker.ceph.com/issues/42248
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
src/librbd/api/DiffIterate.cc

index e4c850f39d0a7c30c77fb3cc38e1ee54fba7e8be..af61cd9e38459703a8a2fb3a2da19f261ea4e97c 100644 (file)
@@ -377,7 +377,25 @@ int DiffIterate<I>::execute() {
 
       if (fast_diff_enabled) {
         const uint64_t object_no = p->second.front().objectno;
-        if (object_diff_state[object_no] != OBJECT_DIFF_STATE_NONE) {
+        if (object_diff_state[object_no] == OBJECT_DIFF_STATE_NONE &&
+            from_snap_id == 0 && !diff_context.parent_diff.empty()) {
+          // no data in child object -- report parent diff instead
+          for (auto& oe : p->second) {
+            for (auto& be : oe.buffer_extents) {
+              interval_set<uint64_t> o;
+              o.insert(off + be.first, be.second);
+              o.intersection_of(diff_context.parent_diff);
+              ldout(cct, 20) << " reporting parent overlap " << o << dendl;
+              for (auto e = o.begin(); e != o.end(); ++e) {
+                r = m_callback(e.get_start(), e.get_len(), true,
+                               m_callback_arg);
+                if (r < 0) {
+                  return r;
+                }
+              }
+            }
+          }
+        } else if (object_diff_state[object_no] != OBJECT_DIFF_STATE_NONE) {
           bool updated = (object_diff_state[object_no] ==
                             OBJECT_DIFF_STATE_UPDATED);
           for (std::vector<ObjectExtent>::iterator q = p->second.begin();