]>
Commit | Line | Data |
---|---|---|
3d016e11 FE |
1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
2 | From: Jens Axboe <axboe@kernel.dk> | |
3 | Date: Mon, 16 Jan 2023 08:55:53 -0700 | |
4 | Subject: [PATCH] block: don't allow multiple bios for IOCB_NOWAIT issue | |
5 | ||
6 | If we're doing a large IO request which needs to be split into multiple | |
7 | bios for issue, then we can run into the same situation as the below | |
8 | marked commit fixes - parts will complete just fine, one or more parts | |
9 | will fail to allocate a request. This will result in a partially | |
10 | completed read or write request, where the caller gets EAGAIN even though | |
11 | parts of the IO completed just fine. | |
12 | ||
13 | Do the same for large bios as we do for splits - fail a NOWAIT request | |
14 | with EAGAIN. This isn't technically fixing an issue in the below marked | |
15 | patch, but for stable purposes, we should have either none of them or | |
16 | both. | |
17 | ||
18 | This depends on: 613b14884b85 ("block: handle bio_split_to_limits() NULL return") | |
19 | ||
20 | Cc: stable@vger.kernel.org # 5.15+ | |
21 | Fixes: 9cea62b2cbab ("block: don't allow splitting of a REQ_NOWAIT bio") | |
22 | Link: https://github.com/axboe/liburing/issues/766 | |
23 | Reported-and-tested-by: Michael Kelley <mikelley@microsoft.com> | |
24 | Signed-off-by: Jens Axboe <axboe@kernel.dk> | |
25 | (commit 67d59247d4b52c917e373f05a807027756ab216f upstream) | |
26 | Signed-off-by: Fiona Ebner <f.ebner@proxmox.com> | |
24d804a0 | 27 | Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com> |
3d016e11 FE |
28 | --- |
29 | block/fops.c | 21 ++++++++++++++++++--- | |
30 | 1 file changed, 18 insertions(+), 3 deletions(-) | |
31 | ||
32 | diff --git a/block/fops.c b/block/fops.c | |
24d804a0 | 33 | index 50d245e8c913..d2e6be4e3d1c 100644 |
3d016e11 FE |
34 | --- a/block/fops.c |
35 | +++ b/block/fops.c | |
36 | @@ -221,6 +221,24 @@ static ssize_t __blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter, | |
37 | bio_endio(bio); | |
38 | break; | |
39 | } | |
40 | + if (iocb->ki_flags & IOCB_NOWAIT) { | |
41 | + /* | |
42 | + * This is nonblocking IO, and we need to allocate | |
43 | + * another bio if we have data left to map. As we | |
44 | + * cannot guarantee that one of the sub bios will not | |
45 | + * fail getting issued FOR NOWAIT and as error results | |
46 | + * are coalesced across all of them, be safe and ask for | |
47 | + * a retry of this from blocking context. | |
48 | + */ | |
49 | + if (unlikely(iov_iter_count(iter))) { | |
50 | + bio_release_pages(bio, false); | |
51 | + bio_clear_flag(bio, BIO_REFFED); | |
52 | + bio_put(bio); | |
53 | + blk_finish_plug(&plug); | |
54 | + return -EAGAIN; | |
55 | + } | |
56 | + bio->bi_opf |= REQ_NOWAIT; | |
57 | + } | |
58 | ||
59 | if (is_read) { | |
60 | if (dio->flags & DIO_SHOULD_DIRTY) | |
61 | @@ -228,9 +246,6 @@ static ssize_t __blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter, | |
62 | } else { | |
63 | task_io_account_write(bio->bi_iter.bi_size); | |
64 | } | |
65 | - if (iocb->ki_flags & IOCB_NOWAIT) | |
66 | - bio->bi_opf |= REQ_NOWAIT; | |
67 | - | |
68 | dio->size += bio->bi_iter.bi_size; | |
69 | pos += bio->bi_iter.bi_size; | |
70 |