Skip to content

Commit f3ff668

Browse files
slegendrMikulas Patocka
authored andcommitted
dm vdo: abort loading dirty VDO with the old recovery journal format
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 <[email protected]> Signed-off-by: Matthew Sakai <[email protected]> Signed-off-by: Mikulas Patocka <[email protected]>
1 parent 47874c9 commit f3ff668

File tree

2 files changed

+24
-4
lines changed

2 files changed

+24
-4
lines changed

drivers/md/dm-vdo/dm-vdo-target.c

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2296,6 +2296,14 @@ static void handle_load_error(struct vdo_completion *completion)
22962296
return;
22972297
}
22982298

2299+
if ((completion->result == VDO_UNSUPPORTED_VERSION) &&
2300+
(vdo->admin.phase == LOAD_PHASE_MAKE_DIRTY)) {
2301+
vdo_log_error("Aborting load due to unsupported version");
2302+
vdo->admin.phase = LOAD_PHASE_FINISHED;
2303+
load_callback(completion);
2304+
return;
2305+
}
2306+
22992307
vdo_log_error_strerror(completion->result,
23002308
"Entering read-only mode due to load error");
23012309
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)
27402748
vdo_log_info("starting device '%s'", device_name);
27412749
result = perform_admin_operation(vdo, LOAD_PHASE_START, load_callback,
27422750
handle_load_error, "load");
2751+
if (result == VDO_UNSUPPORTED_VERSION) {
2752+
/*
2753+
* A component version is not supported. This can happen when the
2754+
* recovery journal metadata is in an old version format. Abort the
2755+
* load without saving the state.
2756+
*/
2757+
vdo->suspend_type = VDO_ADMIN_STATE_SUSPENDING;
2758+
perform_admin_operation(vdo, SUSPEND_PHASE_START,
2759+
suspend_callback, suspend_callback,
2760+
"suspend");
2761+
return result;
2762+
}
2763+
27432764
if ((result != VDO_SUCCESS) && (result != VDO_READ_ONLY)) {
27442765
/*
27452766
* Something has gone very wrong. Make sure everything has drained and
@@ -2811,7 +2832,8 @@ static int vdo_preresume(struct dm_target *ti)
28112832

28122833
vdo_register_thread_device_id(&instance_thread, &vdo->instance);
28132834
result = vdo_preresume_registered(ti, vdo);
2814-
if ((result == VDO_PARAMETER_MISMATCH) || (result == VDO_INVALID_ADMIN_STATE))
2835+
if ((result == VDO_PARAMETER_MISMATCH) || (result == VDO_INVALID_ADMIN_STATE) ||
2836+
(result == VDO_UNSUPPORTED_VERSION))
28152837
result = -EINVAL;
28162838
vdo_unregister_thread_device_id();
28172839
return vdo_status_to_errno(result);

drivers/md/dm-vdo/repair.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1575,9 +1575,7 @@ static int parse_journal_for_recovery(struct repair_completion *repair)
15751575
if (header.metadata_type == VDO_METADATA_RECOVERY_JOURNAL) {
15761576
/* This is an old format block, so we need to upgrade */
15771577
vdo_log_error_strerror(VDO_UNSUPPORTED_VERSION,
1578-
"Recovery journal is in the old format, a read-only rebuild is required.");
1579-
vdo_enter_read_only_mode(repair->completion.vdo,
1580-
VDO_UNSUPPORTED_VERSION);
1578+
"Recovery journal is in the old format. Downgrade and complete recovery, then upgrade with a clean volume");
15811579
return VDO_UNSUPPORTED_VERSION;
15821580
}
15831581

0 commit comments

Comments
 (0)