Move the bdev flag checks into a helper and the blk-mq clone insers so that we can do only a single actual error injection for I/O to partitions instead of doing it twice.
Signed-off-by: Christoph Hellwig <[email protected]> --- block/blk-core.c | 28 ++++++++++++++-------------- block/blk-mq.c | 3 ++- block/blk.h | 5 ++--- include/linux/blk_types.h | 2 -- 4 files changed, 18 insertions(+), 20 deletions(-) diff --git a/block/blk-core.c b/block/blk-core.c index f35e0d3fb127..644888b66f33 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -502,10 +502,9 @@ static int __init setup_fail_make_request(char *str) } __setup("fail_make_request=", setup_fail_make_request); -bool should_fail_request(struct block_device *part, unsigned int bytes) +bool should_fail_request(unsigned int bytes) { - return bdev_test_flag(part, BD_MAKE_IT_FAIL) && - should_fail(&fail_make_request, bytes); + return should_fail(&fail_make_request, bytes); } static int __init fail_make_request_debugfs(void) @@ -539,11 +538,13 @@ static inline void bio_check_ro(struct bio *bio) } } -static int should_fail_bio(struct bio *bio) +static inline bool may_fail_bio(struct bio *bio) { - if (should_fail_request(bdev_whole(bio->bi_bdev), bio->bi_iter.bi_size)) - return -EIO; - return 0; + if (!IS_ENABLED(CONFIG_FAIL_MAKE_REQUEST)) + return false; + return bdev_test_flag(bio->bi_bdev, BD_MAKE_IT_FAIL) || + (bio_flagged(bio, BIO_REMAPPED) && + bdev_test_flag(bdev_whole(bio->bi_bdev), BD_MAKE_IT_FAIL)); } /* @@ -577,8 +578,6 @@ static int blk_partition_remap(struct bio *bio) { struct block_device *p = bio->bi_bdev; - if (unlikely(should_fail_request(p, bio->bi_iter.bi_size))) - return -EIO; if (bio_sectors(bio)) { bio->bi_iter.bi_sector += p->bd_start_sect; trace_block_bio_remap(bio, p->bd_dev, @@ -723,10 +722,13 @@ static void __submit_bio_noacct_mq(struct bio *bio) void submit_bio_noacct_nocheck(struct bio *bio, bool split) { - if (should_fail_bio(bio)) { - bio_io_error(bio); - return; + if (unlikely(may_fail_bio(bio))) { + if (should_fail_request(bio->bi_iter.bi_size)) { + bio_io_error(bio); + return; + } } + blk_cgroup_bio_start(bio); if (!bio_flagged(bio, BIO_TRACE_COMPLETION)) { @@ -799,8 +801,6 @@ void submit_bio_noacct(struct bio *bio) goto not_supported; } - if (should_fail_bio(bio)) - goto end_io; bio_check_ro(bio); if (!bio_flagged(bio, BIO_REMAPPED)) { if (unlikely(bio_check_eod(bio))) diff --git a/block/blk-mq.c b/block/blk-mq.c index 629e16003eb7..bf66645622df 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -3275,7 +3275,8 @@ blk_status_t blk_insert_cloned_request(struct request *rq) return BLK_STS_IOERR; } - if (q->disk && should_fail_request(q->disk->part0, blk_rq_bytes(rq))) + if (q->disk && bdev_test_flag(q->disk->part0, BD_MAKE_IT_FAIL) && + should_fail_request(blk_rq_bytes(rq))) return BLK_STS_IOERR; ret = blk_crypto_rq_get_keyslot(rq); diff --git a/block/blk.h b/block/blk.h index 889a39589356..250a6eee700a 100644 --- a/block/blk.h +++ b/block/blk.h @@ -647,10 +647,9 @@ int disk_register_independent_access_ranges(struct gendisk *disk); void disk_unregister_independent_access_ranges(struct gendisk *disk); #ifdef CONFIG_FAIL_MAKE_REQUEST -bool should_fail_request(struct block_device *part, unsigned int bytes); +bool should_fail_request(unsigned int bytes); #else /* CONFIG_FAIL_MAKE_REQUEST */ -static inline bool should_fail_request(struct block_device *part, - unsigned int bytes) +static inline bool should_fail_request(unsigned int bytes) { return false; } diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h index 8808ee76e73c..4a3cfa857637 100644 --- a/include/linux/blk_types.h +++ b/include/linux/blk_types.h @@ -51,9 +51,7 @@ struct block_device { #define BD_WRITE_HOLDER (1u<<9) #define BD_HAS_SUBMIT_BIO (1u<<10) #define BD_RO_WARNED (1u<<11) -#ifdef CONFIG_FAIL_MAKE_REQUEST #define BD_MAKE_IT_FAIL (1u<<12) -#endif dev_t bd_dev; struct address_space *bd_mapping; /* page cache */ -- 2.53.0
