diff options
author | Ilya Dryomov <idryomov@gmail.com> | 2023-12-08 15:19:02 +0100 |
---|---|---|
committer | Ilya Dryomov <idryomov@gmail.com> | 2023-12-11 17:45:57 +0100 |
commit | 70c1991f225c137abf769111086b6c61abc0ece3 (patch) | |
tree | ca8ad11121d3f6cc099b3f156999d907c64fb6d1 /src/librbd/object_map/DiffRequest.cc | |
parent | test/librbd: expand DiffIterateTest.DiffIterateDiscard (diff) | |
download | ceph-70c1991f225c137abf769111086b6c61abc0ece3.tar.xz ceph-70c1991f225c137abf769111086b6c61abc0ece3.zip |
librbd: OBJECT_PENDING should always be treated as dirty
OBJECT_PENDING is a transition state which normally isn't encountered
in (snapshot) object maps. In case it's encountered, for example when
a snapshot is taken after losing power at the time a discard was being
handled, the object should be treated as dirty and produce a diff as
a result.
Assuming an object is marked OBJECT_PENDING, theoretically there are
four cases with respect to object's state in the next snapshot:
1. OBJECT_NONEXISTENT
2. OBJECT_EXISTS
3. OBJECT_PENDING
4. OBJECT_EXISTS_CLEAN
Prior to commit b81cd2460de7 ("librbd/object_map: diff state machine
should track object existence"), (3) was handled incorrectly (diff set
to DIFF_STATE_NONE instead of DIFF_STATE_UPDATED).
Post commit 399a45e11332 ("librbd/object_map: rbd diff between two
snapshots lists entire image content"), (4) is handled incorrectly
(diff set to DIFF_STATE_DATA instead of DIFF_STATE_DATA_UPDATED).
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Diffstat (limited to '')
-rw-r--r-- | src/librbd/object_map/DiffRequest.cc | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/src/librbd/object_map/DiffRequest.cc b/src/librbd/object_map/DiffRequest.cc index 8820aacc87b..5b785aeaf3c 100644 --- a/src/librbd/object_map/DiffRequest.cc +++ b/src/librbd/object_map/DiffRequest.cc @@ -266,7 +266,11 @@ void DiffRequest<I>::handle_load_object_map(int r) { } } else { // diffing against a snapshot, this is its object map - *diff_it = DIFF_STATE_DATA; + if (object_map_state != OBJECT_PENDING) { + *diff_it = DIFF_STATE_DATA; + } else { + *diff_it = DIFF_STATE_DATA_UPDATED; + } } ldout(cct, 20) << "object state: " << i << " " |