Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'for-6.12/dm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm

Pull device mapper fixes from Mikulas Patocka:
"Revert the patch that made dm-verity restart or panic on I/O errors,
and instead add new explicit options for people who want that
behavior"

* tag 'for-6.12/dm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm:
dm-verity: introduce the options restart_on_error and panic_on_error
Revert: "dm-verity: restart or panic on an I/O error"

+79 -16
+78 -16
drivers/md/dm-verity-target.c
··· 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; ··· 275 273 if (v->mode == DM_VERITY_MODE_LOGGING) 276 274 return 0; 277 275 278 - if (v->mode == DM_VERITY_MODE_RESTART) { 279 - pr_emerg("dm-verity device corrupted\n"); 280 - emergency_restart(); 281 - } 276 + if (v->mode == DM_VERITY_MODE_RESTART) 277 + kernel_restart("dm-verity device corrupted"); 282 278 283 279 if (v->mode == DM_VERITY_MODE_PANIC) 284 280 panic("dm-verity device corrupted"); ··· 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 */ ··· 607 602 if (unlikely(status != BLK_STS_OK) && 608 603 unlikely(!(bio->bi_opf & REQ_RAHEAD)) && 609 604 !verity_is_system_shutting_down()) { 610 - if (v->mode == DM_VERITY_MODE_RESTART || 611 - v->mode == DM_VERITY_MODE_PANIC) 612 - DMERR_LIMIT("%s has error: %s", v->data_dev->name, 613 - blk_status_to_str(status)); 614 - 615 - if (v->mode == DM_VERITY_MODE_RESTART) { 616 - pr_emerg("dm-verity device corrupted\n"); 617 - emergency_restart(); 605 + if (v->error_mode == DM_VERITY_MODE_PANIC) { 606 + panic("dm-verity device has I/O error"); 618 607 } 619 - 620 - if (v->mode == DM_VERITY_MODE_PANIC) 621 - panic("dm-verity device corrupted"); 608 + if (v->error_mode == DM_VERITY_MODE_RESTART) { 609 + static DECLARE_WORK(restart_work, restart_io_error); 610 + queue_work(v->verify_wq, &restart_work); 611 + /* 612 + * We deliberately don't call bio_endio here, because 613 + * the machine will be restarted anyway. 614 + */ 615 + return; 616 + } 622 617 } 623 618 624 619 bio_endio(bio); ··· 829 824 DMEMIT("%02x", v->salt[x]); 830 825 if (v->mode != DM_VERITY_MODE_EIO) 831 826 args++; 827 + if (v->error_mode != DM_VERITY_MODE_EIO) 828 + args++; 832 829 if (verity_fec_is_enabled(v)) 833 830 args += DM_VERITY_OPTS_FEC; 834 831 if (v->zero_digest) ··· 855 848 break; 856 849 case DM_VERITY_MODE_PANIC: 857 850 DMEMIT(DM_VERITY_OPT_PANIC); 851 + break; 852 + default: 853 + BUG(); 854 + } 855 + } 856 + if (v->error_mode != DM_VERITY_MODE_EIO) { 857 + DMEMIT(" "); 858 + switch (v->error_mode) { 859 + case DM_VERITY_MODE_RESTART: 860 + DMEMIT(DM_VERITY_OPT_ERROR_RESTART); 861 + break; 862 + case DM_VERITY_MODE_PANIC: 863 + DMEMIT(DM_VERITY_OPT_ERROR_PANIC); 858 864 break; 859 865 default: 860 866 BUG(); ··· 920 900 break; 921 901 case DM_VERITY_MODE_PANIC: 922 902 DMEMIT(DM_VERITY_OPT_PANIC); 903 + break; 904 + default: 905 + DMEMIT("invalid"); 906 + } 907 + } 908 + if (v->error_mode != DM_VERITY_MODE_EIO) { 909 + DMEMIT(",verity_error_mode="); 910 + switch (v->error_mode) { 911 + case DM_VERITY_MODE_RESTART: 912 + DMEMIT(DM_VERITY_OPT_ERROR_RESTART); 913 + break; 914 + case DM_VERITY_MODE_PANIC: 915 + DMEMIT(DM_VERITY_OPT_ERROR_PANIC); 923 916 break; 924 917 default: 925 918 DMEMIT("invalid"); ··· 1140 1107 return 0; 1141 1108 } 1142 1109 1110 + static inline bool verity_is_verity_error_mode(const char *arg_name) 1111 + { 1112 + return (!strcasecmp(arg_name, DM_VERITY_OPT_ERROR_RESTART) || 1113 + !strcasecmp(arg_name, DM_VERITY_OPT_ERROR_PANIC)); 1114 + } 1115 + 1116 + static int verity_parse_verity_error_mode(struct dm_verity *v, const char *arg_name) 1117 + { 1118 + if (v->error_mode) 1119 + return -EINVAL; 1120 + 1121 + if (!strcasecmp(arg_name, DM_VERITY_OPT_ERROR_RESTART)) 1122 + v->error_mode = DM_VERITY_MODE_RESTART; 1123 + else if (!strcasecmp(arg_name, DM_VERITY_OPT_ERROR_PANIC)) 1124 + v->error_mode = DM_VERITY_MODE_PANIC; 1125 + 1126 + return 0; 1127 + } 1128 + 1143 1129 static int verity_parse_opt_args(struct dm_arg_set *as, struct dm_verity *v, 1144 1130 struct dm_verity_sig_opts *verify_args, 1145 1131 bool only_modifier_opts) ··· 1187 1135 if (only_modifier_opts) 1188 1136 continue; 1189 1137 r = verity_parse_verity_mode(v, arg_name); 1138 + if (r) { 1139 + ti->error = "Conflicting error handling parameters"; 1140 + return r; 1141 + } 1142 + continue; 1143 + 1144 + } else if (verity_is_verity_error_mode(arg_name)) { 1145 + if (only_modifier_opts) 1146 + continue; 1147 + r = verity_parse_verity_error_mode(v, arg_name); 1190 1148 if (r) { 1191 1149 ti->error = "Conflicting error handling parameters"; 1192 1150 return r;
+1
drivers/md/dm-verity.h
··· 64 64 unsigned int digest_size; /* digest size for the current hash algorithm */ 65 65 unsigned int hash_reqsize; /* the size of temporary space for crypto */ 66 66 enum verity_mode mode; /* mode for handling verification errors */ 67 + enum verity_mode error_mode;/* mode for handling I/O errors */ 67 68 unsigned int corrupted_errs;/* Number of errors for corrupted blocks */ 68 69 69 70 struct workqueue_struct *verify_wq;