From: Susan LeGendre-McGhee <slege...@redhat.com>

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 <slege...@redhat.com>
Signed-off-by: Matthew Sakai <msa...@redhat.com>
---
 drivers/md/dm-vdo/dm-vdo-target.c | 24 +++++++++++++++++++++++-
 drivers/md/dm-vdo/repair.c        |  4 +---
 2 files changed, 24 insertions(+), 4 deletions(-)

diff --git a/drivers/md/dm-vdo/dm-vdo-target.c 
b/drivers/md/dm-vdo/dm-vdo-target.c
index ed1d775de0d3..5b5660404669 100644
--- a/drivers/md/dm-vdo/dm-vdo-target.c
+++ b/drivers/md/dm-vdo/dm-vdo-target.c
@@ -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);
diff --git a/drivers/md/dm-vdo/repair.c b/drivers/md/dm-vdo/repair.c
index b6f3d0710a21..28475eee0058 100644
--- a/drivers/md/dm-vdo/repair.c
+++ b/drivers/md/dm-vdo/repair.c
@@ -1574,9 +1574,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;
                }
 
-- 
2.45.2


Reply via email to