]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
dm vdo: abort loading dirty VDO with the old recovery journal format
authorSusan LeGendre-McGhee <slegendr@redhat.com>
Fri, 19 Jul 2024 21:52:32 +0000 (17:52 -0400)
committerMikulas Patocka <mpatocka@redhat.com>
Wed, 21 Aug 2024 11:11:34 +0000 (13:11 +0200)
Abort the load process with status code VDO_UNSUPPORTED_VERSION
without forcing read-only mode when a journal block with the
old format version is detected.

Forcing the VDO volume into read-only mode and thus requiring
a read-only rebuild should only be done when absolutely necessary.

Signed-off-by: Susan LeGendre-McGhee <slegendr@redhat.com>
Signed-off-by: Matthew Sakai <msakai@redhat.com>
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
drivers/md/dm-vdo/dm-vdo-target.c
drivers/md/dm-vdo/repair.c

index 4b94f5718ed7af1d6d88d43fffda80e9f10278e7..0e04c20216825f4c3574f504f680848e1b5c2317 100644 (file)
@@ -2296,6 +2296,14 @@ static void handle_load_error(struct vdo_completion *completion)
                return;
        }
 
+       if ((completion->result == VDO_UNSUPPORTED_VERSION) &&
+           (vdo->admin.phase == LOAD_PHASE_MAKE_DIRTY)) {
+               vdo_log_error("Aborting load due to unsupported version");
+               vdo->admin.phase = LOAD_PHASE_FINISHED;
+               load_callback(completion);
+               return;
+       }
+
        vdo_log_error_strerror(completion->result,
                               "Entering read-only mode due to load error");
        vdo->admin.phase = LOAD_PHASE_WAIT_FOR_READ_ONLY;
@@ -2740,6 +2748,19 @@ static int vdo_preresume_registered(struct dm_target *ti, struct vdo *vdo)
                vdo_log_info("starting device '%s'", device_name);
                result = perform_admin_operation(vdo, LOAD_PHASE_START, load_callback,
                                                 handle_load_error, "load");
+               if (result == VDO_UNSUPPORTED_VERSION) {
+                        /*
+                         * A component version is not supported. This can happen when the
+                         * recovery journal metadata is in an old version format. Abort the
+                         * load without saving the state.
+                         */
+                       vdo->suspend_type = VDO_ADMIN_STATE_SUSPENDING;
+                       perform_admin_operation(vdo, SUSPEND_PHASE_START,
+                                               suspend_callback, suspend_callback,
+                                               "suspend");
+                       return result;
+               }
+
                if ((result != VDO_SUCCESS) && (result != VDO_READ_ONLY)) {
                        /*
                         * Something has gone very wrong. Make sure everything has drained and
@@ -2811,7 +2832,8 @@ static int vdo_preresume(struct dm_target *ti)
 
        vdo_register_thread_device_id(&instance_thread, &vdo->instance);
        result = vdo_preresume_registered(ti, vdo);
-       if ((result == VDO_PARAMETER_MISMATCH) || (result == VDO_INVALID_ADMIN_STATE))
+       if ((result == VDO_PARAMETER_MISMATCH) || (result == VDO_INVALID_ADMIN_STATE) ||
+           (result == VDO_UNSUPPORTED_VERSION))
                result = -EINVAL;
        vdo_unregister_thread_device_id();
        return vdo_status_to_errno(result);
index 7e0009d2f67d5dcaf134867c43993f2b9c33fec3..8aae78bb8a05f71bc51c1f74797171c0a56143e8 100644 (file)
@@ -1575,9 +1575,7 @@ static int parse_journal_for_recovery(struct repair_completion *repair)
                if (header.metadata_type == VDO_METADATA_RECOVERY_JOURNAL) {
                        /* This is an old format block, so we need to upgrade */
                        vdo_log_error_strerror(VDO_UNSUPPORTED_VERSION,
-                                              "Recovery journal is in the old format, a read-only rebuild is required.");
-                       vdo_enter_read_only_mode(repair->completion.vdo,
-                                                VDO_UNSUPPORTED_VERSION);
+                                              "Recovery journal is in the old format. Downgrade and complete recovery, then upgrade with a clean volume");
                        return VDO_UNSUPPORTED_VERSION;
                }