36
36
#define DM_VERITY_OPT_LOGGING "ignore_corruption"
37
37
#define DM_VERITY_OPT_RESTART "restart_on_corruption"
38
38
#define DM_VERITY_OPT_PANIC "panic_on_corruption"
39
+ #define DM_VERITY_OPT_ERROR_RESTART "restart_on_error"
40
+ #define DM_VERITY_OPT_ERROR_PANIC "panic_on_error"
39
41
#define DM_VERITY_OPT_IGN_ZEROES "ignore_zero_blocks"
40
42
#define DM_VERITY_OPT_AT_MOST_ONCE "check_at_most_once"
41
43
#define DM_VERITY_OPT_TASKLET_VERIFY "try_verify_in_tasklet"
42
44
43
- #define DM_VERITY_OPTS_MAX (4 + DM_VERITY_OPTS_FEC + \
45
+ #define DM_VERITY_OPTS_MAX (5 + DM_VERITY_OPTS_FEC + \
44
46
DM_VERITY_ROOT_HASH_VERIFICATION_OPTS)
45
47
46
48
static unsigned int dm_verity_prefetch_cluster = DM_VERITY_DEFAULT_PREFETCH_SIZE ;
@@ -273,10 +275,8 @@ static int verity_handle_err(struct dm_verity *v, enum verity_block_type type,
273
275
if (v -> mode == DM_VERITY_MODE_LOGGING )
274
276
return 0 ;
275
277
276
- if (v -> mode == DM_VERITY_MODE_RESTART ) {
277
- pr_emerg ("dm-verity device corrupted\n" );
278
- emergency_restart ();
279
- }
278
+ if (v -> mode == DM_VERITY_MODE_RESTART )
279
+ kernel_restart ("dm-verity device corrupted" );
280
280
281
281
if (v -> mode == DM_VERITY_MODE_PANIC )
282
282
panic ("dm-verity device corrupted" );
@@ -585,6 +585,11 @@ static inline bool verity_is_system_shutting_down(void)
585
585
|| system_state == SYSTEM_RESTART ;
586
586
}
587
587
588
+ static void restart_io_error (struct work_struct * w )
589
+ {
590
+ kernel_restart ("dm-verity device has I/O error" );
591
+ }
592
+
588
593
/*
589
594
* End one "io" structure with a given error.
590
595
*/
@@ -602,18 +607,18 @@ static void verity_finish_io(struct dm_verity_io *io, blk_status_t status)
602
607
if (unlikely (status != BLK_STS_OK ) &&
603
608
unlikely (!(bio -> bi_opf & REQ_RAHEAD )) &&
604
609
!verity_is_system_shutting_down ()) {
605
- if (v -> mode == DM_VERITY_MODE_RESTART ||
606
- v -> mode == DM_VERITY_MODE_PANIC )
607
- DMERR_LIMIT ("%s has error: %s" , v -> data_dev -> name ,
608
- blk_status_to_str (status ));
609
-
610
- if (v -> mode == DM_VERITY_MODE_RESTART ) {
611
- pr_emerg ("dm-verity device corrupted\n" );
612
- emergency_restart ();
610
+ if (v -> error_mode == DM_VERITY_MODE_PANIC ) {
611
+ panic ("dm-verity device has I/O error" );
612
+ }
613
+ if (v -> error_mode == DM_VERITY_MODE_RESTART ) {
614
+ static DECLARE_WORK (restart_work , restart_io_error ) ;
615
+ queue_work (v -> verify_wq , & restart_work );
616
+ /*
617
+ * We deliberately don't call bio_endio here, because
618
+ * the machine will be restarted anyway.
619
+ */
620
+ return ;
613
621
}
614
-
615
- if (v -> mode == DM_VERITY_MODE_PANIC )
616
- panic ("dm-verity device corrupted" );
617
622
}
618
623
619
624
bio_endio (bio );
@@ -824,6 +829,8 @@ static void verity_status(struct dm_target *ti, status_type_t type,
824
829
DMEMIT ("%02x" , v -> salt [x ]);
825
830
if (v -> mode != DM_VERITY_MODE_EIO )
826
831
args ++ ;
832
+ if (v -> error_mode != DM_VERITY_MODE_EIO )
833
+ args ++ ;
827
834
if (verity_fec_is_enabled (v ))
828
835
args += DM_VERITY_OPTS_FEC ;
829
836
if (v -> zero_digest )
@@ -853,6 +860,19 @@ static void verity_status(struct dm_target *ti, status_type_t type,
853
860
BUG ();
854
861
}
855
862
}
863
+ if (v -> error_mode != DM_VERITY_MODE_EIO ) {
864
+ DMEMIT (" " );
865
+ switch (v -> error_mode ) {
866
+ case DM_VERITY_MODE_RESTART :
867
+ DMEMIT (DM_VERITY_OPT_ERROR_RESTART );
868
+ break ;
869
+ case DM_VERITY_MODE_PANIC :
870
+ DMEMIT (DM_VERITY_OPT_ERROR_PANIC );
871
+ break ;
872
+ default :
873
+ BUG ();
874
+ }
875
+ }
856
876
if (v -> zero_digest )
857
877
DMEMIT (" " DM_VERITY_OPT_IGN_ZEROES );
858
878
if (v -> validated_blocks )
@@ -905,6 +925,19 @@ static void verity_status(struct dm_target *ti, status_type_t type,
905
925
DMEMIT ("invalid" );
906
926
}
907
927
}
928
+ if (v -> error_mode != DM_VERITY_MODE_EIO ) {
929
+ DMEMIT (",verity_error_mode=" );
930
+ switch (v -> error_mode ) {
931
+ case DM_VERITY_MODE_RESTART :
932
+ DMEMIT (DM_VERITY_OPT_ERROR_RESTART );
933
+ break ;
934
+ case DM_VERITY_MODE_PANIC :
935
+ DMEMIT (DM_VERITY_OPT_ERROR_PANIC );
936
+ break ;
937
+ default :
938
+ DMEMIT ("invalid" );
939
+ }
940
+ }
908
941
DMEMIT (";" );
909
942
break ;
910
943
}
@@ -1107,6 +1140,25 @@ static int verity_parse_verity_mode(struct dm_verity *v, const char *arg_name)
1107
1140
return 0 ;
1108
1141
}
1109
1142
1143
+ static inline bool verity_is_verity_error_mode (const char * arg_name )
1144
+ {
1145
+ return (!strcasecmp (arg_name , DM_VERITY_OPT_ERROR_RESTART ) ||
1146
+ !strcasecmp (arg_name , DM_VERITY_OPT_ERROR_PANIC ));
1147
+ }
1148
+
1149
+ static int verity_parse_verity_error_mode (struct dm_verity * v , const char * arg_name )
1150
+ {
1151
+ if (v -> error_mode )
1152
+ return - EINVAL ;
1153
+
1154
+ if (!strcasecmp (arg_name , DM_VERITY_OPT_ERROR_RESTART ))
1155
+ v -> error_mode = DM_VERITY_MODE_RESTART ;
1156
+ else if (!strcasecmp (arg_name , DM_VERITY_OPT_ERROR_PANIC ))
1157
+ v -> error_mode = DM_VERITY_MODE_PANIC ;
1158
+
1159
+ return 0 ;
1160
+ }
1161
+
1110
1162
static int verity_parse_opt_args (struct dm_arg_set * as , struct dm_verity * v ,
1111
1163
struct dm_verity_sig_opts * verify_args ,
1112
1164
bool only_modifier_opts )
@@ -1141,6 +1193,16 @@ static int verity_parse_opt_args(struct dm_arg_set *as, struct dm_verity *v,
1141
1193
}
1142
1194
continue ;
1143
1195
1196
+ } else if (verity_is_verity_error_mode (arg_name )) {
1197
+ if (only_modifier_opts )
1198
+ continue ;
1199
+ r = verity_parse_verity_error_mode (v , arg_name );
1200
+ if (r ) {
1201
+ ti -> error = "Conflicting error handling parameters" ;
1202
+ return r ;
1203
+ }
1204
+ continue ;
1205
+
1144
1206
} else if (!strcasecmp (arg_name , DM_VERITY_OPT_IGN_ZEROES )) {
1145
1207
if (only_modifier_opts )
1146
1208
continue ;
0 commit comments