diff mbox series

[10/17] mm/filemap: Move the iocb checks into filemap_update_page

Message ID 20201102184312.25926-11-willy@infradead.org (mailing list archive)
State New, archived
Headers show
Series Refactor generic_file_buffered_read | expand

Commit Message

Matthew Wilcox Nov. 2, 2020, 6:43 p.m. UTC
We don't need to give up when a special request sees a !Uptodate page.
We may be able to satisfy the read from a partially-uptodate page.

Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
 mm/filemap.c | 28 ++++++++++++----------------
 1 file changed, 12 insertions(+), 16 deletions(-)

Comments

Kent Overstreet Nov. 2, 2020, 7:45 p.m. UTC | #1
On Mon, Nov 02, 2020 at 06:43:05PM +0000, Matthew Wilcox (Oracle) wrote:
> We don't need to give up when a special request sees a !Uptodate page.
> We may be able to satisfy the read from a partially-uptodate page.
> 
> Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>

Reviewed-by: Kent Overstreet <kent.overstreet@gmail.com>
Christoph Hellwig Nov. 3, 2020, 7:41 a.m. UTC | #2
Looks good,

Reviewed-by: Christoph Hellwig <hch@lst.de>
diff mbox series

Patch

diff --git a/mm/filemap.c b/mm/filemap.c
index ebb14fdec0cc..41b90243f4ee 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -2230,17 +2230,21 @@  static int filemap_read_page(struct file *file, struct address_space *mapping,
 
 static int filemap_update_page(struct kiocb *iocb,
 		struct address_space *mapping, struct iov_iter *iter,
-		struct page *page, loff_t pos, loff_t count)
+		struct page *page, loff_t pos, loff_t count, bool first)
 {
 	struct inode *inode = mapping->host;
-	int error;
+	int error = -EAGAIN;
 
-	if (iocb->ki_flags & IOCB_WAITQ) {
-		error = lock_page_async(page, iocb->ki_waitq);
-		if (error)
+	if (!trylock_page(page)) {
+		if (iocb->ki_flags & (IOCB_NOWAIT | IOCB_NOIO))
 			goto error;
-	} else {
-		if (!trylock_page(page)) {
+		if (iocb->ki_flags & IOCB_WAITQ) {
+			if (!first)
+				goto error;
+			error = __lock_page_async(page, iocb->ki_waitq);
+			if (error)
+				goto error;
+		} else {
 			put_and_wait_on_page_locked(page, TASK_KILLABLE);
 			return AOP_TRUNCATED_PAGE;
 		}
@@ -2359,16 +2363,8 @@  static int filemap_get_pages(struct kiocb *iocb, struct iov_iter *iter,
 		}
 
 		if (!PageUptodate(page)) {
-			if ((iocb->ki_flags & IOCB_NOWAIT) ||
-			    ((iocb->ki_flags & IOCB_WAITQ) && nr_got > 1)) {
-				put_page(page);
-				nr_got--;
-				err = -EAGAIN;
-				goto err;
-			}
-
 			err = filemap_update_page(iocb, mapping, iter, page,
-					pg_pos, pg_count);
+					pg_pos, pg_count, nr_got == 1);
 			if (err)
 				nr_got--;
 		}