summaryrefslogtreecommitdiffstats
path: root/src/librbd/api/DiffIterate.cc
diff options
context:
space:
mode:
authorJason Dillaman <dillaman@redhat.com>2019-12-23 17:34:07 +0100
committerJason Dillaman <dillaman@redhat.com>2019-12-23 17:34:07 +0100
commitb61f83b6f0b5913484cca060e090f81d6215f6cb (patch)
tree98c7bb75af84839dbc463f0cb2da277025543bb4 /src/librbd/api/DiffIterate.cc
parentMerge pull request #32368 from xiexingguo/wip-balancer-efficiency-4 (diff)
downloadceph-b61f83b6f0b5913484cca060e090f81d6215f6cb.tar.xz
ceph-b61f83b6f0b5913484cca060e090f81d6215f6cb.zip
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 <dillaman@redhat.com>
Diffstat (limited to '')
-rw-r--r--src/librbd/api/DiffIterate.cc20
1 files changed, 19 insertions, 1 deletions
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<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();