This method can be used to check if bio-based device supports IO polling
or not. For mq devices, checking for hw queue in polling mode is
adequate, while the sanity check shall be implementation specific for
bio-based devices. For example, dm device needs to check if all
underlying devices are capable of IO polling.

Though bio-based device may have done the sanity check during the
device initialization phase, cacheing the result of this sanity check
(such as by cacheing in the queue_flags) may not work. Because for dm
devices, users could change the state of the underlying devices through
'/sys/block/<dev>/io_poll', bypassing the dm device above. In this case,
the cached result of the very beginning sanity check could be
out-of-date. Thus the sanity check needs to be done every time 'io_poll'
is to be modified.

Signed-off-by: Jeffle Xu <[email protected]>
---
 block/blk-sysfs.c      | 14 +++++++++++---
 include/linux/blkdev.h |  1 +
 2 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c
index b513f1683af0..f11fedefc37d 100644
--- a/block/blk-sysfs.c
+++ b/block/blk-sysfs.c
@@ -420,9 +420,17 @@ static ssize_t queue_poll_store(struct request_queue *q, 
const char *page,
        unsigned long poll_on;
        ssize_t ret;
 
-       if (!q->tag_set || q->tag_set->nr_maps <= HCTX_TYPE_POLL ||
-           !q->tag_set->map[HCTX_TYPE_POLL].nr_queues)
-               return -EINVAL;
+       if (queue_is_mq(q)) {
+               if (!q->tag_set || q->tag_set->nr_maps <= HCTX_TYPE_POLL ||
+                   !q->tag_set->map[HCTX_TYPE_POLL].nr_queues)
+                       return -EINVAL;
+       } else {
+               struct gendisk *disk = queue_to_disk(q);
+
+               if (!disk->fops->poll_capable ||
+                   !disk->fops->poll_capable(disk))
+                       return -EINVAL;
+       }
 
        ret = queue_var_store(&poll_on, page, count);
        if (ret < 0)
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index ebe16f55cba4..8a84088642ce 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -1854,6 +1854,7 @@ static inline void blk_ksm_unregister(struct 
request_queue *q) { }
 struct block_device_operations {
        blk_qc_t (*submit_bio) (struct bio *bio);
        int (*poll)(struct request_queue *q, blk_qc_t cookie);
+       bool (*poll_capable)(struct gendisk *disk);
        int (*open) (struct block_device *, fmode_t);
        void (*release) (struct gendisk *, fmode_t);
        int (*rw_page)(struct block_device *, sector_t, struct page *, unsigned 
int);
-- 
2.27.0

--
dm-devel mailing list
[email protected]
https://listman.redhat.com/mailman/listinfo/dm-devel

Reply via email to