.. | .. |
---|
124 | 124 | * Direction r or w? |
---|
125 | 125 | */ |
---|
126 | 126 | arg_name = dm_shift_arg(as); |
---|
127 | | - if (!strcasecmp(arg_name, "w")) |
---|
| 127 | + if (arg_name && !strcasecmp(arg_name, "w")) |
---|
128 | 128 | fc->corrupt_bio_rw = WRITE; |
---|
129 | | - else if (!strcasecmp(arg_name, "r")) |
---|
| 129 | + else if (arg_name && !strcasecmp(arg_name, "r")) |
---|
130 | 130 | fc->corrupt_bio_rw = READ; |
---|
131 | 131 | else { |
---|
132 | 132 | ti->error = "Invalid corrupt bio direction (r or w)"; |
---|
.. | .. |
---|
280 | 280 | struct flakey_c *fc = ti->private; |
---|
281 | 281 | |
---|
282 | 282 | bio_set_dev(bio, fc->dev->bdev); |
---|
283 | | - if (bio_sectors(bio) || bio_op(bio) == REQ_OP_ZONE_RESET) |
---|
| 283 | + if (bio_sectors(bio) || op_is_zone_mgmt(bio_op(bio))) |
---|
284 | 284 | bio->bi_iter.bi_sector = |
---|
285 | 285 | flakey_map_sector(ti, bio->bi_iter.bi_sector); |
---|
286 | 286 | } |
---|
.. | .. |
---|
301 | 301 | */ |
---|
302 | 302 | bio_for_each_segment(bvec, bio, iter) { |
---|
303 | 303 | if (bio_iter_len(bio, iter) > corrupt_bio_byte) { |
---|
304 | | - char *segment = (page_address(bio_iter_page(bio, iter)) |
---|
305 | | - + bio_iter_offset(bio, iter)); |
---|
| 304 | + char *segment; |
---|
| 305 | + struct page *page = bio_iter_page(bio, iter); |
---|
| 306 | + if (unlikely(page == ZERO_PAGE(0))) |
---|
| 307 | + break; |
---|
| 308 | + segment = (page_address(page) + bio_iter_offset(bio, iter)); |
---|
306 | 309 | segment[corrupt_bio_byte] = fc->corrupt_bio_value; |
---|
307 | 310 | DMDEBUG("Corrupting data bio=%p by writing %u to byte %u " |
---|
308 | 311 | "(rw=%c bi_opf=%u bi_sector=%llu size=%u)\n", |
---|
.. | .. |
---|
322 | 325 | struct per_bio_data *pb = dm_per_bio_data(bio, sizeof(struct per_bio_data)); |
---|
323 | 326 | pb->bio_submitted = false; |
---|
324 | 327 | |
---|
325 | | - /* Do not fail reset zone */ |
---|
326 | | - if (bio_op(bio) == REQ_OP_ZONE_RESET) |
---|
327 | | - goto map_bio; |
---|
328 | | - |
---|
329 | | - /* We need to remap reported zones, so remember the BIO iter */ |
---|
330 | | - if (bio_op(bio) == REQ_OP_ZONE_REPORT) |
---|
| 328 | + if (op_is_zone_mgmt(bio_op(bio))) |
---|
331 | 329 | goto map_bio; |
---|
332 | 330 | |
---|
333 | 331 | /* Are we alive ? */ |
---|
.. | .. |
---|
364 | 362 | /* |
---|
365 | 363 | * Corrupt matching writes. |
---|
366 | 364 | */ |
---|
367 | | - if (fc->corrupt_bio_byte && (fc->corrupt_bio_rw == WRITE)) { |
---|
368 | | - if (all_corrupt_bio_flags_match(bio, fc)) |
---|
369 | | - corrupt_bio_data(bio, fc); |
---|
| 365 | + if (fc->corrupt_bio_byte) { |
---|
| 366 | + if (fc->corrupt_bio_rw == WRITE) { |
---|
| 367 | + if (all_corrupt_bio_flags_match(bio, fc)) |
---|
| 368 | + corrupt_bio_data(bio, fc); |
---|
| 369 | + } |
---|
370 | 370 | goto map_bio; |
---|
371 | 371 | } |
---|
372 | 372 | |
---|
.. | .. |
---|
388 | 388 | struct flakey_c *fc = ti->private; |
---|
389 | 389 | struct per_bio_data *pb = dm_per_bio_data(bio, sizeof(struct per_bio_data)); |
---|
390 | 390 | |
---|
391 | | - if (bio_op(bio) == REQ_OP_ZONE_RESET) |
---|
| 391 | + if (op_is_zone_mgmt(bio_op(bio))) |
---|
392 | 392 | return DM_ENDIO_DONE; |
---|
393 | | - |
---|
394 | | - if (bio_op(bio) == REQ_OP_ZONE_REPORT) { |
---|
395 | | - dm_remap_zone_report(ti, bio, fc->start); |
---|
396 | | - return DM_ENDIO_DONE; |
---|
397 | | - } |
---|
398 | 393 | |
---|
399 | 394 | if (!*error && pb->bio_submitted && (bio_data_dir(bio) == READ)) { |
---|
400 | | - if (fc->corrupt_bio_byte && (fc->corrupt_bio_rw == READ) && |
---|
401 | | - all_corrupt_bio_flags_match(bio, fc)) { |
---|
402 | | - /* |
---|
403 | | - * Corrupt successful matching READs while in down state. |
---|
404 | | - */ |
---|
405 | | - corrupt_bio_data(bio, fc); |
---|
406 | | - |
---|
| 395 | + if (fc->corrupt_bio_byte) { |
---|
| 396 | + if ((fc->corrupt_bio_rw == READ) && |
---|
| 397 | + all_corrupt_bio_flags_match(bio, fc)) { |
---|
| 398 | + /* |
---|
| 399 | + * Corrupt successful matching READs while in down state. |
---|
| 400 | + */ |
---|
| 401 | + corrupt_bio_data(bio, fc); |
---|
| 402 | + } |
---|
407 | 403 | } else if (!test_bit(DROP_WRITES, &fc->flags) && |
---|
408 | 404 | !test_bit(ERROR_WRITES, &fc->flags)) { |
---|
409 | 405 | /* |
---|
.. | .. |
---|
468 | 464 | return 0; |
---|
469 | 465 | } |
---|
470 | 466 | |
---|
| 467 | +#ifdef CONFIG_BLK_DEV_ZONED |
---|
| 468 | +static int flakey_report_zones(struct dm_target *ti, |
---|
| 469 | + struct dm_report_zones_args *args, unsigned int nr_zones) |
---|
| 470 | +{ |
---|
| 471 | + struct flakey_c *fc = ti->private; |
---|
| 472 | + sector_t sector = flakey_map_sector(ti, args->next_sector); |
---|
| 473 | + |
---|
| 474 | + args->start = fc->start; |
---|
| 475 | + return blkdev_report_zones(fc->dev->bdev, sector, nr_zones, |
---|
| 476 | + dm_report_zones_cb, args); |
---|
| 477 | +} |
---|
| 478 | +#endif |
---|
| 479 | + |
---|
471 | 480 | static int flakey_iterate_devices(struct dm_target *ti, iterate_devices_callout_fn fn, void *data) |
---|
472 | 481 | { |
---|
473 | 482 | struct flakey_c *fc = ti->private; |
---|
.. | .. |
---|
479 | 488 | .name = "flakey", |
---|
480 | 489 | .version = {1, 5, 0}, |
---|
481 | 490 | #ifdef CONFIG_BLK_DEV_ZONED |
---|
482 | | - .features = DM_TARGET_ZONED_HM, |
---|
| 491 | + .features = DM_TARGET_ZONED_HM | DM_TARGET_PASSES_CRYPTO, |
---|
| 492 | + .report_zones = flakey_report_zones, |
---|
| 493 | +#else |
---|
| 494 | + .features = DM_TARGET_PASSES_CRYPTO, |
---|
483 | 495 | #endif |
---|
484 | 496 | .module = THIS_MODULE, |
---|
485 | 497 | .ctr = flakey_ctr, |
---|