From b9b94131a1201558ad54fab453e8e272e1d093cd Mon Sep 17 00:00:00 2001 From: Weston Andros Adamson Date: Thu, 14 Aug 2014 17:39:33 -0400 Subject: [PATCH] nfs: can_coalesce_requests must enforce contiguity MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Commit ca19b58bd2977d7850cbb72d5dc56f2c647c36c5 "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: Toralf Förster Signed-off-by: Weston Andros Adamson Signed-off-by: Trond Myklebust --- fs/nfs/pagelist.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c index a1d1de7b97c5f..932c6cc27a766 100644 --- a/fs/nfs/pagelist.c +++ b/fs/nfs/pagelist.c @@ -823,6 +823,14 @@ static bool nfs_can_coalesce_requests(struct nfs_page *prev, return false; if (req_offset(req) != req_offset(prev) + prev->wb_bytes) 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); WARN_ON_ONCE(size > req->wb_bytes); -- 2.39.5