diff mbox series

[1/3] mm: Do not pass iter into generic_file_buffered_read_get_pages()

Message ID 20210120160611.26853-2-jack@suse.cz
State New
Headers show
Series fs: Hole punch vs page cache filling races | expand

Commit Message

Jan Kara Jan. 20, 2021, 4:06 p.m. UTC
generic_file_buffered_read_get_pages() needs to only know the length we
want to read and whether partially uptodate pages are accepted. Also
principially this function just loads pages into page cache so it does
not need to know about user buffers to copy data to. Pass the length and
whether partially uptodate pages are acceptable into
generic_file_buffered_read_get_pages() instead of iter.

Signed-off-by: Jan Kara <jack@suse.cz>
---
 mm/filemap.c | 24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)

Comments

Christoph Hellwig Jan. 20, 2021, 4:18 p.m. UTC | #1
This whole code has a massive refactoring pending that barely didn't
make it in the last merge window.  willy, do you plan to resend it
ASAP?
diff mbox series

Patch

diff --git a/mm/filemap.c b/mm/filemap.c
index 5c9d564317a5..7029bada8e90 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -2235,7 +2235,7 @@  generic_file_buffered_read_readpage(struct kiocb *iocb,
 static struct page *
 generic_file_buffered_read_pagenotuptodate(struct kiocb *iocb,
 					   struct file *filp,
-					   struct iov_iter *iter,
+					   bool partial_page,
 					   struct page *page,
 					   loff_t pos, loff_t count)
 {
@@ -2264,8 +2264,8 @@  generic_file_buffered_read_pagenotuptodate(struct kiocb *iocb,
 	if (inode->i_blkbits == PAGE_SHIFT ||
 			!mapping->a_ops->is_partially_uptodate)
 		goto page_not_up_to_date;
-	/* pipes can't handle partially uptodate pages */
-	if (unlikely(iov_iter_is_pipe(iter)))
+	/* Some reads (e.g. pipes) don't accept partially uptodate pages */
+	if (unlikely(!partial_page))
 		goto page_not_up_to_date;
 	if (!trylock_page(page))
 		goto page_not_up_to_date;
@@ -2304,8 +2304,7 @@  generic_file_buffered_read_pagenotuptodate(struct kiocb *iocb,
 }
 
 static struct page *
-generic_file_buffered_read_no_cached_page(struct kiocb *iocb,
-					  struct iov_iter *iter)
+generic_file_buffered_read_no_cached_page(struct kiocb *iocb)
 {
 	struct file *filp = iocb->ki_filp;
 	struct address_space *mapping = filp->f_mapping;
@@ -2335,7 +2334,7 @@  generic_file_buffered_read_no_cached_page(struct kiocb *iocb,
 }
 
 static int generic_file_buffered_read_get_pages(struct kiocb *iocb,
-						struct iov_iter *iter,
+						size_t len, bool partial_page,
 						struct page **pages,
 						unsigned int nr)
 {
@@ -2343,7 +2342,7 @@  static int generic_file_buffered_read_get_pages(struct kiocb *iocb,
 	struct address_space *mapping = filp->f_mapping;
 	struct file_ra_state *ra = &filp->f_ra;
 	pgoff_t index = iocb->ki_pos >> PAGE_SHIFT;
-	pgoff_t last_index = (iocb->ki_pos + iter->count + PAGE_SIZE-1) >> PAGE_SHIFT;
+	pgoff_t last_index = (iocb->ki_pos + len + PAGE_SIZE - 1) >> PAGE_SHIFT;
 	int i, j, nr_got, err = 0;
 
 	nr = min_t(unsigned long, last_index - index, nr);
@@ -2364,7 +2363,7 @@  static int generic_file_buffered_read_get_pages(struct kiocb *iocb,
 	if (nr_got)
 		goto got_pages;
 
-	pages[0] = generic_file_buffered_read_no_cached_page(iocb, iter);
+	pages[0] = generic_file_buffered_read_no_cached_page(iocb);
 	err = PTR_ERR_OR_ZERO(pages[0]);
 	if (!IS_ERR_OR_NULL(pages[0]))
 		nr_got = 1;
@@ -2374,7 +2373,7 @@  static int generic_file_buffered_read_get_pages(struct kiocb *iocb,
 		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;
+		loff_t pg_count = iocb->ki_pos + len - pg_pos;
 
 		if (PageReadahead(page)) {
 			if (iocb->ki_flags & IOCB_NOIO) {
@@ -2399,7 +2398,8 @@  static int generic_file_buffered_read_get_pages(struct kiocb *iocb,
 			}
 
 			page = generic_file_buffered_read_pagenotuptodate(iocb,
-					filp, iter, page, pg_pos, pg_count);
+					filp, partial_page, page, pg_pos,
+					pg_count);
 			if (IS_ERR_OR_NULL(page)) {
 				for (j = i + 1; j < nr_got; j++)
 					put_page(pages[j]);
@@ -2478,8 +2478,8 @@  ssize_t generic_file_buffered_read(struct kiocb *iocb,
 			iocb->ki_flags |= IOCB_NOWAIT;
 
 		i = 0;
-		pg_nr = generic_file_buffered_read_get_pages(iocb, iter,
-							     pages, nr_pages);
+		pg_nr = generic_file_buffered_read_get_pages(iocb, iter->count,
+				!iov_iter_is_pipe(iter), pages, nr_pages);
 		if (pg_nr < 0) {
 			error = pg_nr;
 			break;