Skip to content

Commit d252293

Browse files
committed
dm-verity: introduce the options restart_on_error and panic_on_error
JIRA: https://issues.redhat.com/browse/RHEL-59523 Upstream Status: kernel/git/torvalds/linux.git commit f811b83 Author: Mikulas Patocka <mpatocka@redhat.com> Date: Wed Oct 2 16:03:41 2024 +0200 dm-verity: introduce the options restart_on_error and panic_on_error This patch introduces the options restart_on_error and panic_on_error on dm-verity. Previously, restarting on error was handled by the patch e6a3531, but Google engineers wanted to have a special option for it. Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Suggested-by: Sami Tolvanen <samitolvanen@google.com> Suggested-by: Will Drewry <wad@chromium.org> Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
1 parent 91c2daf commit d252293

File tree

2 files changed

+83
-1
lines changed

2 files changed

+83
-1
lines changed

drivers/md/dm-verity-target.c

Lines changed: 82 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,13 @@
3535
#define DM_VERITY_OPT_LOGGING "ignore_corruption"
3636
#define DM_VERITY_OPT_RESTART "restart_on_corruption"
3737
#define DM_VERITY_OPT_PANIC "panic_on_corruption"
38+
#define DM_VERITY_OPT_ERROR_RESTART "restart_on_error"
39+
#define DM_VERITY_OPT_ERROR_PANIC "panic_on_error"
3840
#define DM_VERITY_OPT_IGN_ZEROES "ignore_zero_blocks"
3941
#define DM_VERITY_OPT_AT_MOST_ONCE "check_at_most_once"
4042
#define DM_VERITY_OPT_TASKLET_VERIFY "try_verify_in_tasklet"
4143

42-
#define DM_VERITY_OPTS_MAX (4 + DM_VERITY_OPTS_FEC + \
44+
#define DM_VERITY_OPTS_MAX (5 + DM_VERITY_OPTS_FEC + \
4345
DM_VERITY_ROOT_HASH_VERIFICATION_OPTS)
4446

4547
static unsigned int dm_verity_prefetch_cluster = DM_VERITY_DEFAULT_PREFETCH_SIZE;
@@ -582,6 +584,11 @@ static inline bool verity_is_system_shutting_down(void)
582584
|| system_state == SYSTEM_RESTART;
583585
}
584586

587+
static void restart_io_error(struct work_struct *w)
588+
{
589+
kernel_restart("dm-verity device has I/O error");
590+
}
591+
585592
/*
586593
* End one "io" structure with a given error.
587594
*/
@@ -596,6 +603,23 @@ static void verity_finish_io(struct dm_verity_io *io, blk_status_t status)
596603
if (!static_branch_unlikely(&use_bh_wq_enabled) || !io->in_bh)
597604
verity_fec_finish_io(io);
598605

606+
if (unlikely(status != BLK_STS_OK) &&
607+
unlikely(!(bio->bi_opf & REQ_RAHEAD)) &&
608+
!verity_is_system_shutting_down()) {
609+
if (v->error_mode == DM_VERITY_MODE_PANIC) {
610+
panic("dm-verity device has I/O error");
611+
}
612+
if (v->error_mode == DM_VERITY_MODE_RESTART) {
613+
static DECLARE_WORK(restart_work, restart_io_error);
614+
queue_work(v->verify_wq, &restart_work);
615+
/*
616+
* We deliberately don't call bio_endio here, because
617+
* the machine will be restarted anyway.
618+
*/
619+
return;
620+
}
621+
}
622+
599623
bio_endio(bio);
600624
}
601625

@@ -804,6 +828,8 @@ static void verity_status(struct dm_target *ti, status_type_t type,
804828
DMEMIT("%02x", v->salt[x]);
805829
if (v->mode != DM_VERITY_MODE_EIO)
806830
args++;
831+
if (v->error_mode != DM_VERITY_MODE_EIO)
832+
args++;
807833
if (verity_fec_is_enabled(v))
808834
args += DM_VERITY_OPTS_FEC;
809835
if (v->zero_digest)
@@ -833,6 +859,19 @@ static void verity_status(struct dm_target *ti, status_type_t type,
833859
BUG();
834860
}
835861
}
862+
if (v->error_mode != DM_VERITY_MODE_EIO) {
863+
DMEMIT(" ");
864+
switch (v->error_mode) {
865+
case DM_VERITY_MODE_RESTART:
866+
DMEMIT(DM_VERITY_OPT_ERROR_RESTART);
867+
break;
868+
case DM_VERITY_MODE_PANIC:
869+
DMEMIT(DM_VERITY_OPT_ERROR_PANIC);
870+
break;
871+
default:
872+
BUG();
873+
}
874+
}
836875
if (v->zero_digest)
837876
DMEMIT(" " DM_VERITY_OPT_IGN_ZEROES);
838877
if (v->validated_blocks)
@@ -885,6 +924,19 @@ static void verity_status(struct dm_target *ti, status_type_t type,
885924
DMEMIT("invalid");
886925
}
887926
}
927+
if (v->error_mode != DM_VERITY_MODE_EIO) {
928+
DMEMIT(",verity_error_mode=");
929+
switch (v->error_mode) {
930+
case DM_VERITY_MODE_RESTART:
931+
DMEMIT(DM_VERITY_OPT_ERROR_RESTART);
932+
break;
933+
case DM_VERITY_MODE_PANIC:
934+
DMEMIT(DM_VERITY_OPT_ERROR_PANIC);
935+
break;
936+
default:
937+
DMEMIT("invalid");
938+
}
939+
}
888940
DMEMIT(";");
889941
break;
890942
}
@@ -1051,6 +1103,25 @@ static int verity_parse_verity_mode(struct dm_verity *v, const char *arg_name)
10511103
return 0;
10521104
}
10531105

1106+
static inline bool verity_is_verity_error_mode(const char *arg_name)
1107+
{
1108+
return (!strcasecmp(arg_name, DM_VERITY_OPT_ERROR_RESTART) ||
1109+
!strcasecmp(arg_name, DM_VERITY_OPT_ERROR_PANIC));
1110+
}
1111+
1112+
static int verity_parse_verity_error_mode(struct dm_verity *v, const char *arg_name)
1113+
{
1114+
if (v->error_mode)
1115+
return -EINVAL;
1116+
1117+
if (!strcasecmp(arg_name, DM_VERITY_OPT_ERROR_RESTART))
1118+
v->error_mode = DM_VERITY_MODE_RESTART;
1119+
else if (!strcasecmp(arg_name, DM_VERITY_OPT_ERROR_PANIC))
1120+
v->error_mode = DM_VERITY_MODE_PANIC;
1121+
1122+
return 0;
1123+
}
1124+
10541125
static int verity_parse_opt_args(struct dm_arg_set *as, struct dm_verity *v,
10551126
struct dm_verity_sig_opts *verify_args,
10561127
bool only_modifier_opts)
@@ -1085,6 +1156,16 @@ static int verity_parse_opt_args(struct dm_arg_set *as, struct dm_verity *v,
10851156
}
10861157
continue;
10871158

1159+
} else if (verity_is_verity_error_mode(arg_name)) {
1160+
if (only_modifier_opts)
1161+
continue;
1162+
r = verity_parse_verity_error_mode(v, arg_name);
1163+
if (r) {
1164+
ti->error = "Conflicting error handling parameters";
1165+
return r;
1166+
}
1167+
continue;
1168+
10881169
} else if (!strcasecmp(arg_name, DM_VERITY_OPT_IGN_ZEROES)) {
10891170
if (only_modifier_opts)
10901171
continue;

drivers/md/dm-verity.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ struct dm_verity {
6060
unsigned int digest_size; /* digest size for the current hash algorithm */
6161
unsigned int hash_reqsize; /* the size of temporary space for crypto */
6262
enum verity_mode mode; /* mode for handling verification errors */
63+
enum verity_mode error_mode;/* mode for handling I/O errors */
6364
unsigned int corrupted_errs;/* Number of errors for corrupted blocks */
6465

6566
struct workqueue_struct *verify_wq;

0 commit comments

Comments
 (0)