diff mbox series

[1/1] block: end bio with BLK_STS_AGAIN in case of non-mq devs and REQ_NOWAIT

Message ID 20191217155407.928386-1-rpenyaev@suse.de (mailing list archive)
State New, archived
Headers show
Series [1/1] block: end bio with BLK_STS_AGAIN in case of non-mq devs and REQ_NOWAIT | expand

Commit Message

Roman Penyaev Dec. 17, 2019, 3:54 p.m. UTC
Non-mq devs do not honor REQ_NOWAIT so give a chance to the caller to repeat
request gracefully on -EAGAIN error.

The problem is well reproduced using io_uring:

   mkfs.ext4 /dev/ram0
   mount /dev/ram0 /mnt

   # Preallocate a file
   dd if=/dev/zero of=/mnt/file bs=1M count=1

   # Start fio with io_uring and get -EIO
   fio --rw=write --ioengine=io_uring --size=1M --direct=1 --name=job --filename=/mnt/file

Signed-off-by: Roman Penyaev <rpenyaev@suse.de>
---
 block/blk-core.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

Comments

Jens Axboe Dec. 17, 2019, 4:02 p.m. UTC | #1
On 12/17/19 8:54 AM, Roman Penyaev wrote:
> Non-mq devs do not honor REQ_NOWAIT so give a chance to the caller to repeat
> request gracefully on -EAGAIN error.
> 
> The problem is well reproduced using io_uring:
> 
>    mkfs.ext4 /dev/ram0
>    mount /dev/ram0 /mnt
> 
>    # Preallocate a file
>    dd if=/dev/zero of=/mnt/file bs=1M count=1
> 
>    # Start fio with io_uring and get -EIO
>    fio --rw=write --ioengine=io_uring --size=1M --direct=1 --name=job --filename=/mnt/file

Thanks, this makes a lot of sense, doing -EIO for that case is wrong. Applied
for 5.5.
diff mbox series

Patch

diff --git a/block/blk-core.c b/block/blk-core.c
index d5e668ec751b..1075aaff606d 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -886,11 +886,14 @@  generic_make_request_checks(struct bio *bio)
 	}
 
 	/*
-	 * For a REQ_NOWAIT based request, return -EOPNOTSUPP
-	 * if queue is not a request based queue.
+	 * Non-mq queues do not honor REQ_NOWAIT, so complete a bio
+	 * with BLK_STS_AGAIN status in order to catch -EAGAIN and
+	 * to give a chance to the caller to repeat request gracefully.
 	 */
-	if ((bio->bi_opf & REQ_NOWAIT) && !queue_is_mq(q))
-		goto not_supported;
+	if ((bio->bi_opf & REQ_NOWAIT) && !queue_is_mq(q)) {
+		status = BLK_STS_AGAIN;
+		goto end_io;
+	}
 
 	if (should_fail_bio(bio))
 		goto end_io;