Commit 08c01d23 authored by Weston Andros Adamson's avatar Weston Andros Adamson Committed by Greg Kroah-Hartman

nfs: can_coalesce_requests must enforce contiguity

commit 78270e8f upstream.

Commit 6094f838
"nfs: allow coalescing of subpage requests" got rid of the requirement
that requests cover whole pages, but it made some incorrect assumptions.

It turns out that callers of this interface can map adjacent requests
(by file position as seen by req_offset + req->wb_bytes) to different pages,
even when they could share a page. An example is the direct I/O interface -
iov_iter_get_pages_alloc may return one segment with a partial page filled
and the next segment (which is adjacent in the file position) starts with a
new page.
Reported-by: default avatarToralf Förster <toralf.foerster@gmx.de>
Signed-off-by: default avatarWeston Andros Adamson <dros@primarydata.com>
Signed-off-by: default avatarTrond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 42e32385
...@@ -833,6 +833,14 @@ static bool nfs_can_coalesce_requests(struct nfs_page *prev, ...@@ -833,6 +833,14 @@ static bool nfs_can_coalesce_requests(struct nfs_page *prev,
return false; return false;
if (req_offset(req) != req_offset(prev) + prev->wb_bytes) if (req_offset(req) != req_offset(prev) + prev->wb_bytes)
return false; return false;
if (req->wb_page == prev->wb_page) {
if (req->wb_pgbase != prev->wb_pgbase + prev->wb_bytes)
return false;
} else {
if (req->wb_pgbase != 0 ||
prev->wb_pgbase + prev->wb_bytes != PAGE_CACHE_SIZE)
return false;
}
} }
size = pgio->pg_ops->pg_test(pgio, prev, req); size = pgio->pg_ops->pg_test(pgio, prev, req);
WARN_ON_ONCE(size > req->wb_bytes); WARN_ON_ONCE(size > req->wb_bytes);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment