From: Jason Dillaman Date: Mon, 23 Dec 2019 16:34:07 +0000 (-0500) Subject: librbd: diff iterate with fast-diff now correctly includes parent X-Git-Tag: v15.1.0~367^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=refs%2Fpull%2F32403%2Fhead;p=ceph.git librbd: diff iterate with fast-diff now correctly includes parent 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 --- diff --git a/src/librbd/api/DiffIterate.cc b/src/librbd/api/DiffIterate.cc index e4c850f39d0..af61cd9e384 100644 --- a/src/librbd/api/DiffIterate.cc +++ b/src/librbd/api/DiffIterate.cc @@ -377,7 +377,25 @@ int DiffIterate::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 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::iterator q = p->second.begin();