From 31d31f29f0883e0726cf21388a46ee5b7367f2e0 Mon Sep 17 00:00:00 2001 From: Jason Dillaman Date: Mon, 23 Dec 2019 11:34:07 -0500 Subject: [PATCH] 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 (cherry picked from commit b61f83b) --- src/librbd/api/DiffIterate.cc | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/librbd/api/DiffIterate.cc b/src/librbd/api/DiffIterate.cc index b99907dbebbb0..88b665f58d2b9 100644 --- a/src/librbd/api/DiffIterate.cc +++ b/src/librbd/api/DiffIterate.cc @@ -372,7 +372,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(); -- 2.39.5