From: sashiko-bot@kernel.org
To: "Pranjal Shrivastava" <praan@google.com>
Cc: "Anna Schumaker" <anna@kernel.org>,
"Jeff Layton" <jlayton@kernel.org>,
linux-pci@vger.kernel.org, "Chuck Lever" <cel@kernel.org>
Subject: Re: [PATCH v6 4/5] nfs: migrate direct I/O to iov_iter_extract_pages
Date: Fri, 14 Aug 2026 14:48:04 +0000 [thread overview]
Message-ID: <20260814144804.D41911F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260814143255.861084-5-praan@google.com>
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
Pre-existing issues:
- [High] If request creation or insertion fails mid-chunk, the iterator is not reverted for the remaining un-scheduled bytes, leading to iterator desync.
- [High] If `iov_iter_extract_pages` returns 0, the scheduling loops will spin infinitely without making progress.
--
--- Patch [4]: [PATCH v6 4/5] nfs: migrate direct I/O to iov_iter_extract_pages ---
commit 5228f408a5f9a33be680decc8231db65a3427585
Author: Pranjal Shrivastava <praan@google.com>
nfs: migrate direct I/O to iov_iter_extract_pages
Migrate the NFS Direct I/O path away from the legacy
iov_iter_get_pages_alloc2() API to the modern iov_iter_extract_pages API.
The transition aligns NFS with the modern VFS extraction model and serves
as a preparatory step for supporting requirements such as page pinning
via GUP for DMA.
> diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
> index 96995736fac2a..a1479fbf4f9e1 100644
> --- a/fs/nfs/direct.c
> +++ b/fs/nfs/direct.c
[ ... ]
> @@ -348,16 +348,17 @@ static ssize_t nfs_direct_read_schedule_iovec(struct nfs_direct_req *dreq,
> inode_dio_begin(inode);
>
> while (iov_iter_count(iter)) {
> - struct page **pagevec;
> + struct page **pagevec = NULL;
> size_t bytes;
> size_t pgbase;
> unsigned npages, i;
> + bool pinned = iov_iter_extract_will_pin(iter);
>
> - result = iov_iter_get_pages_alloc2(iter, &pagevec,
> - rsize, &pgbase);
> + result = iov_iter_extract_pages(iter, &pagevec,
> + rsize, ~0U, 0, &pgbase);
> if (result < 0)
> break;
[Severity: High]
This is a pre-existing issue, but if iov_iter_extract_pages() returns 0,
will this loop spin indefinitely?
The outer loop in nfs_direct_read_schedule_iovec() relies on
iov_iter_count(iter) > 0 to terminate. If iov_iter_extract_pages() returns
0 (which can happen if zero pages are pinned), the result < 0 check won't
catch it.
This leaves the iterator unadvanced and bytes = 0, causing the loop to
repeat indefinitely and potentially leading to a kernel hang.
Should the check be updated to if (result <= 0)?
> -
> +
> bytes = result;
> npages = (result + pgbase + PAGE_SIZE - 1) / PAGE_SIZE;
> for (i = 0; i < npages; i++) {
> @@ -371,7 +366,7 @@ static ssize_t nfs_direct_read_schedule_iovec(struct nfs_direct_req *dreq,
> unsigned int req_len = min_t(size_t, bytes, PAGE_SIZE - pgbase);
> /* XXX do we need to do the eof zeroing found in async_filler? */
> req = nfs_page_create_from_page(dreq->ctx, pagevec[i],
> - false, pgbase, pos,
> + pinned, pgbase, pos,
> req_len);
> if (IS_ERR(req)) {
> result = PTR_ERR(req);
> @@ -380,6 +375,7 @@ static ssize_t nfs_direct_read_schedule_iovec(struct nfs_direct_req *dreq,
> if (!nfs_pageio_add_request(&desc, req)) {
> result = desc.pg_error;
> nfs_release_request(req);
> + i++;
> break;
> }
[Severity: High]
This is a pre-existing issue, but does this early break cause the iterator
to become desynchronized?
iov_iter_extract_pages() advances the iterator by the total extracted bytes.
If the inner loop breaks early here (e.g. because nfs_pageio_add_request()
fails), the remaining unprocessed bytes in the chunk are skipped, but the
iterator is never reverted for those skipped bytes.
The caller calculates the revert amount based on successfully processed
bytes, so the iterator remains incorrectly advanced. If the VFS retries the
remaining data, it might resume from the wrong offset and silently skip
data.
Does this path need to call iov_iter_revert() for the unprocessed bytes?
[ ... ]
> @@ -888,13 +888,14 @@ static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq,
>
> NFS_I(inode)->write_io += iov_iter_count(iter);
> while (iov_iter_count(iter)) {
> - struct page **pagevec;
> + struct page **pagevec = NULL;
> size_t bytes;
> size_t pgbase;
> unsigned npages, i;
> + bool pinned = iov_iter_extract_will_pin(iter);
>
> - result = iov_iter_get_pages_alloc2(iter, &pagevec,
> - wsize, &pgbase);
> + result = iov_iter_extract_pages(iter, &pagevec,
> + wsize, ~0U, 0, &pgbase);
> if (result < 0)
> break;
[Severity: High]
This isn't a bug introduced by this patch, but similar to the read path,
if iov_iter_extract_pages() returns 0 here, will it result in an infinite
loop in nfs_direct_write_schedule_iovec()?
[ ... ]
> @@ -938,6 +938,7 @@ static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq,
> if (desc.pg_error < 0 && desc.pg_error != -EAGAIN) {
> result = desc.pg_error;
> nfs_unlock_and_release_request(req);
> + i++;
> break;
> }
[Severity: High]
This is a pre-existing issue, but this write path seems to have the same
iterator advancement leak as the read path when breaking early on hard
errors. Should it also revert the iterator for the unprocessed bytes?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260814143255.861084-1-praan@google.com?part=4
next prev parent reply other threads:[~2026-08-14 14:48 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-14 14:32 [PATCH v6 0/5] nfs: modernize direct I/O path Pranjal Shrivastava
2026-08-14 14:32 ` [PATCH v6 1/5] nfs: make nfs_page pin-aware Pranjal Shrivastava
2026-08-14 14:46 ` sashiko-bot
2026-08-14 15:04 ` Pranjal Shrivastava
2026-08-14 14:32 ` [PATCH v6 2/5] nfs: track number of pinned pages in nfs_page Pranjal Shrivastava
2026-08-14 14:47 ` sashiko-bot
2026-08-14 15:14 ` Pranjal Shrivastava
2026-08-14 14:32 ` [PATCH v6 3/5] nfs: introduce nfs_release_request_list helper Pranjal Shrivastava
2026-08-14 14:38 ` sashiko-bot
2026-08-14 14:32 ` [PATCH v6 4/5] nfs: migrate direct I/O to iov_iter_extract_pages Pranjal Shrivastava
2026-08-14 14:48 ` sashiko-bot [this message]
2026-08-14 14:32 ` [PATCH v6 5/5] nfs: introduce nfs_direct_extract_pages helper Pranjal Shrivastava
2026-08-14 14:40 ` sashiko-bot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260814144804.D41911F000E9@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=anna@kernel.org \
--cc=cel@kernel.org \
--cc=jlayton@kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=praan@google.com \
--cc=sashiko-reviews@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox