--- zzzz-none-000/linux-5.4.213/drivers/md/dm-table.c 2022-09-15 10:04:56.000000000 +0000 +++ miami-7690-761/linux-5.4.213/drivers/md/dm-table.c 2024-05-29 11:19:51.000000000 +0000 @@ -928,15 +928,21 @@ return true; } -static int device_is_rq_stackable(struct dm_target *ti, struct dm_dev *dev, - sector_t start, sector_t len, void *data) +struct verify_rq_based_data { + unsigned sq_count; + unsigned mq_count; +}; + +static int device_is_rq_based(struct dm_target *ti, struct dm_dev *dev, + sector_t start, sector_t len, void *data) { - struct block_device *bdev = dev->bdev; - struct request_queue *q = bdev_get_queue(bdev); + struct request_queue *q = bdev_get_queue(dev->bdev); + struct verify_rq_based_data *v = data; - /* request-based cannot stack on partitions! */ - if (bdev != bdev->bd_contains) - return false; + if (queue_is_mq(q)) + v->mq_count++; + else + v->sq_count++; return queue_is_mq(q); } @@ -945,6 +951,7 @@ { unsigned i; unsigned bio_based = 0, request_based = 0, hybrid = 0; + struct verify_rq_based_data v = {.sq_count = 0, .mq_count = 0}; struct dm_target *tgt; struct list_head *devices = dm_table_get_devices(t); enum dm_queue_mode live_md_type = dm_get_md_type(t->md); @@ -1037,10 +1044,14 @@ /* Non-request-stackable devices can't be used for request-based dm */ if (!tgt->type->iterate_devices || - !tgt->type->iterate_devices(tgt, device_is_rq_stackable, NULL)) { + !tgt->type->iterate_devices(tgt, device_is_rq_based, &v)) { DMERR("table load rejected: including non-request-stackable devices"); return -EINVAL; } + if (v.sq_count > 0) { + DMERR("table load rejected: not all devices are blk-mq request-stackable"); + return -EINVAL; + } return 0; }