]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: OBJECT_PENDING should always be treated as dirty
authorIlya Dryomov <idryomov@gmail.com>
Fri, 8 Dec 2023 14:19:02 +0000 (15:19 +0100)
committerIlya Dryomov <idryomov@gmail.com>
Wed, 17 Jan 2024 17:19:55 +0000 (18:19 +0100)
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>
(cherry picked from commit 70c1991f225c137abf769111086b6c61abc0ece3)

src/librbd/object_map/DiffRequest.cc

index 8820aacc87bbba4db5f37ba0b6c56519ace750ff..5b785aeaf3c7db5c1df69f4096bbee4416dcb66c 100644 (file)
@@ -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 << " "