summaryrefslogtreecommitdiffstats
path: root/src/librbd/object_map/DiffRequest.cc
diff options
context:
space:
mode:
authorIlya Dryomov <idryomov@gmail.com>2023-12-08 15:19:02 +0100
committerIlya Dryomov <idryomov@gmail.com>2023-12-11 17:45:57 +0100
commit70c1991f225c137abf769111086b6c61abc0ece3 (patch)
treeca8ad11121d3f6cc099b3f156999d907c64fb6d1 /src/librbd/object_map/DiffRequest.cc
parenttest/librbd: expand DiffIterateTest.DiffIterateDiscard (diff)
downloadceph-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.cc6
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 << " "