From: Jason Dillaman Date: Wed, 6 May 2015 21:31:26 +0000 (-0400) Subject: librbd: fast diff is incorrectly flagging objects as updated X-Git-Tag: v9.0.2~229^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=baebe744925fab227ce91374152c2bc4aaaa6052;p=ceph.git librbd: fast diff is incorrectly flagging objects as updated If the diff_iterate call doesn't start with the first snapshot, unmodified objects in future snapshots / HEAD are incorrectly flagged as modified. Signed-off-by: Jason Dillaman --- diff --git a/src/librbd/internal.cc b/src/librbd/internal.cc index 809dfee90b75..05be815b3b31 100644 --- a/src/librbd/internal.cc +++ b/src/librbd/internal.cc @@ -69,6 +69,7 @@ int diff_object_map(ImageCtx* ictx, uint64_t from_snap_id, uint64_t to_snap_id, assert(ictx->snap_lock.is_locked()); CephContext* cct = ictx->cct; + bool diff_from_start = (from_snap_id == 0); if (from_snap_id == 0) { if (!ictx->snaps.empty()) { from_snap_id = ictx->snaps.front(); @@ -82,6 +83,7 @@ int diff_object_map(ImageCtx* ictx, uint64_t from_snap_id, uint64_t to_snap_id, uint64_t current_snap_id = from_snap_id; uint64_t next_snap_id = to_snap_id; BitVector<2> prev_object_map; + bool prev_object_map_valid = false; while (true) { uint64_t current_size = ictx->size; if (current_snap_id != CEPH_NOSNAP) { @@ -130,6 +132,9 @@ int diff_object_map(ImageCtx* ictx, uint64_t from_snap_id, uint64_t to_snap_id, uint64_t overlap = MIN(object_map.size(), prev_object_map.size()); for (uint64_t i = 0; i < overlap; ++i) { + ldout(cct, 20) << __func__ << ": object state: " << i << " " + << static_cast(prev_object_map[i]) + << "->" << static_cast(object_map[i]) << dendl; if (object_map[i] == OBJECT_NONEXISTENT) { if (prev_object_map[i] != OBJECT_NONEXISTENT) { (*object_diff_state)[i] = OBJECT_DIFF_STATE_HOLE; @@ -143,8 +148,11 @@ int diff_object_map(ImageCtx* ictx, uint64_t from_snap_id, uint64_t to_snap_id, ldout(cct, 20) << "diff_object_map: computed overlap diffs" << dendl; object_diff_state->resize(object_map.size()); - if (object_map.size() > prev_object_map.size()) { + if (object_map.size() > prev_object_map.size() && + (diff_from_start || prev_object_map_valid)) { for (uint64_t i = overlap; i < object_diff_state->size(); ++i) { + ldout(cct, 20) << __func__ << ": object state: " << i << " " + << "->" << static_cast(object_map[i]) << dendl; if (object_map[i] == OBJECT_NONEXISTENT) { (*object_diff_state)[i] = OBJECT_DIFF_STATE_NONE; } else { @@ -159,6 +167,7 @@ int diff_object_map(ImageCtx* ictx, uint64_t from_snap_id, uint64_t to_snap_id, } current_snap_id = next_snap_id; prev_object_map = object_map; + prev_object_map_valid = true; } return 0; }