]> www.infradead.org Git - users/hch/block.git/commitdiff
mm: simplify generic_file_buffered_read_no_cached_page
authorChristoph Hellwig <hch@lst.de>
Fri, 30 Oct 2020 15:36:52 +0000 (16:36 +0100)
committerChristoph Hellwig <hch@lst.de>
Fri, 30 Oct 2020 15:38:12 +0000 (16:38 +0100)
Return an errno and add a new by reference argument for the allocated
page, which allows to cleanup the error unwindining in the function
and the caller.  Also rename the function to filemap_new_page which is
both shorter and more descriptive.

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

index 798de4bdeb546f027abfd4efdd55f8f091e2a2bc..94033d8f2310d9d76b0951a6a6f57a1ce9e9f58e 100644 (file)
@@ -2300,41 +2300,27 @@ put_page:
        return error;
 }
 
-static struct page *
-generic_file_buffered_read_no_cached_page(struct kiocb *iocb,
-                                         struct iov_iter *iter)
+static int filemap_new_page(struct kiocb *iocb, struct iov_iter *iter,
+               struct page **page)
 {
-       struct file *filp = iocb->ki_filp;
-       struct address_space *mapping = filp->f_mapping;
+       struct address_space *mapping = iocb->ki_filp->f_mapping;
+       gfp_t gfp = mapping_gfp_constraint(mapping, GFP_KERNEL);
        pgoff_t index = iocb->ki_pos >> PAGE_SHIFT;
-       struct page *page;
        int error;
 
        if (iocb->ki_flags & IOCB_NOIO)
-               return ERR_PTR(-EAGAIN);
+               return -EAGAIN;
 
-       /*
-        * Ok, it wasn't cached, so we need to create a new
-        * page..
-        */
-       page = page_cache_alloc(mapping);
+       *page = page_cache_alloc(mapping);
        if (!page)
-               return ERR_PTR(-ENOMEM);
-
-       error = add_to_page_cache_lru(page, mapping, index,
-                                     mapping_gfp_constraint(mapping, GFP_KERNEL));
+               return -ENOMEM;
+       error = add_to_page_cache_lru(*page, mapping, index, gfp);
        if (error) {
-               put_page(page);
-               return error != -EEXIST ? ERR_PTR(error) : NULL;
+               put_page(*page);
+               return error;
        }
 
-       error = filemap_readpage(iocb, page);
-       if (error) {
-               if (error == AOP_TRUNCATED_PAGE)
-                       return NULL;
-               return ERR_PTR(error);
-       }
-       return page;
+       return filemap_readpage(iocb, *page);
 }
 
 static int generic_file_buffered_read_get_pages(struct kiocb *iocb,
@@ -2366,18 +2352,14 @@ find_page:
        nr_got = find_get_pages_contig(mapping, index, nr, pages);
        if (nr_got)
                goto got_pages;
-
-       pages[0] = generic_file_buffered_read_no_cached_page(iocb, iter);
-       err = PTR_ERR_OR_ZERO(pages[0]);
-       if (!IS_ERR_OR_NULL(pages[0]))
+       err = filemap_new_page(iocb, iter, &pages[0]);
+       if (!err)
                nr_got = 1;
 got_pages:
        for (i = 0; i < nr_got; i++) {
                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;
@@ -2387,12 +2369,9 @@ got_pages:
 
        if (likely(nr_got))
                return nr_got;
-       if (err)
-               return err;
-       /*
-        * No pages and no error means we raced and should retry:
-        */
-       goto find_page;
+       if (err == -EEXIST || err == AOP_TRUNCATED_PAGE)
+               goto find_page;
+       return err;
 }
 
 /**