| From 4977d121bc9bc5138d4d48b85469123001859573 Mon Sep 17 00:00:00 2001 |
| From: Naohiro Aota <naohiro.aota@wdc.com> |
| Date: Wed, 28 Oct 2020 16:25:36 +0900 |
| Subject: block: advance iov_iter on bio_add_hw_page failure |
| |
| From: Naohiro Aota <naohiro.aota@wdc.com> |
| |
| commit 4977d121bc9bc5138d4d48b85469123001859573 upstream. |
| |
| When the bio's size reaches max_append_sectors, bio_add_hw_page returns |
| 0 then __bio_iov_append_get_pages returns -EINVAL. This is an expected |
| result of building a small enough bio not to be split in the IO path. |
| However, iov_iter is not advanced in this case, causing the same pages |
| are filled for the bio again and again. |
| |
| Fix the case by properly advancing the iov_iter for already processed |
| pages. |
| |
| Fixes: 0512a75b98f8 ("block: Introduce REQ_OP_ZONE_APPEND") |
| Cc: stable@vger.kernel.org # 5.8+ |
| Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> |
| Signed-off-by: Naohiro Aota <naohiro.aota@wdc.com> |
| Signed-off-by: Jens Axboe <axboe@kernel.dk> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| block/bio.c | 11 +++++++---- |
| 1 file changed, 7 insertions(+), 4 deletions(-) |
| |
| --- a/block/bio.c |
| +++ b/block/bio.c |
| @@ -1046,6 +1046,7 @@ static int __bio_iov_append_get_pages(st |
| ssize_t size, left; |
| unsigned len, i; |
| size_t offset; |
| + int ret = 0; |
| |
| if (WARN_ON_ONCE(!max_append_sectors)) |
| return 0; |
| @@ -1068,15 +1069,17 @@ static int __bio_iov_append_get_pages(st |
| |
| len = min_t(size_t, PAGE_SIZE - offset, left); |
| if (bio_add_hw_page(q, bio, page, len, offset, |
| - max_append_sectors, &same_page) != len) |
| - return -EINVAL; |
| + max_append_sectors, &same_page) != len) { |
| + ret = -EINVAL; |
| + break; |
| + } |
| if (same_page) |
| put_page(page); |
| offset = 0; |
| } |
| |
| - iov_iter_advance(iter, size); |
| - return 0; |
| + iov_iter_advance(iter, size - left); |
| + return ret; |
| } |
| |
| /** |