]> www.infradead.org Git - users/hch/block.git/commitdiff
mm: handle readahead in generic_file_buffered_read_pagenotuptodate
authorChristoph Hellwig <hch@lst.de>
Fri, 30 Oct 2020 15:15:40 +0000 (16:15 +0100)
committerChristoph Hellwig <hch@lst.de>
Fri, 30 Oct 2020 15:38:11 +0000 (16:38 +0100)
Move the calculation of the per-page variables and the readahead handling
from the only caller into generic_file_buffered_read_pagenotuptodate,
which now becomes a routine to handle everything related to bringing
one page uptodate and thus is renamed to filemap_read_one_page.

Signed-off-by: Christoph Hellwig <hch@lst.de>
mm/filemap.c

index 934ed93b1fb32523a0cb27d17411d1134b562487..798de4bdeb546f027abfd4efdd55f8f091e2a2bc 100644 (file)
@@ -2217,13 +2217,26 @@ out_put_page:
        return error;
 }
 
-static int generic_file_buffered_read_pagenotuptodate(struct kiocb *iocb,
-               struct iov_iter *iter, struct page *page, loff_t pos,
-               loff_t count, bool first)
+static int filemap_make_page_uptodate(struct kiocb *iocb, struct iov_iter *iter,
+               struct page *page, pgoff_t pg_index, bool first)
 {
-       struct address_space *mapping = iocb->ki_filp->f_mapping;
+       struct file *file = iocb->ki_filp;
+       struct address_space *mapping = file->f_mapping;
+       loff_t last = iocb->ki_pos + iter->count;
+       pgoff_t last_index = (last + PAGE_SIZE - 1) >> PAGE_SHIFT;
+       loff_t pos = max(iocb->ki_pos, (loff_t)pg_index << PAGE_SHIFT);
        int error = -EAGAIN;
 
+       if (PageReadahead(page)) {
+               if (iocb->ki_flags & IOCB_NOIO)
+                       goto put_page;
+               page_cache_async_readahead(mapping, &file->f_ra, file, page,
+                                          pg_index, last_index - pg_index);
+       }
+
+       if (PageUptodate(page))
+               return 0;
+
        if (iocb->ki_flags & IOCB_NOWAIT)
                goto put_page;
 
@@ -2255,8 +2268,8 @@ static int generic_file_buffered_read_pagenotuptodate(struct kiocb *iocb,
        /* Did it get truncated before we got the lock? */
        if (!page->mapping)
                goto page_not_up_to_date_locked;
-       if (!mapping->a_ops->is_partially_uptodate(page,
-                               pos & ~PAGE_MASK, count))
+       if (!mapping->a_ops->is_partially_uptodate(page, pos & ~PAGE_MASK,
+                       last - pos))
                goto page_not_up_to_date_locked;
 
 unlock_page:
@@ -2360,35 +2373,15 @@ find_page:
                nr_got = 1;
 got_pages:
        for (i = 0; i < nr_got; i++) {
-               struct page *page = pages[i];
-               pgoff_t pg_index = index + i;
-               loff_t pg_pos = max(iocb->ki_pos,
-                                   (loff_t) pg_index << PAGE_SHIFT);
-               loff_t pg_count = iocb->ki_pos + iter->count - pg_pos;
-
-               if (PageReadahead(page)) {
-                       if (iocb->ki_flags & IOCB_NOIO) {
-                               for (j = i; j < nr_got; j++)
-                                       put_page(pages[j]);
-                               nr_got = i;
-                               err = -EAGAIN;
-                               break;
-                       }
-                       page_cache_async_readahead(mapping, ra, filp, page,
-                                       pg_index, last_index - pg_index);
-               }
-
-               if (!PageUptodate(page)) {
-                       err = generic_file_buffered_read_pagenotuptodate(iocb,
-                                       iter, page, pg_pos, pg_count, i == 0);
-                       if (err) {
-                               if (err == AOP_TRUNCATED_PAGE)
-                                       err = 0;
-                               for (j = i + 1; j < nr_got; j++)
-                                       put_page(pages[j]);
-                               nr_got = i;
-                               break;
-                       }
+               err = filemap_make_page_uptodate(iocb, iter, pages[i],
+                               index + i, i == 0);
+               if (err) {
+                       if (err == AOP_TRUNCATED_PAGE)
+                               err = 0;
+                       for (j = i + 1; j < nr_got; j++)
+                               put_page(pages[j]);
+                       nr_got = i;
+                       break;
                }
        }