All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jens Axboe <axboe@kernel.dk>
To: sedat.dilek@gmail.com
Cc: io-uring@vger.kernel.org, linux-fsdevel@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-mm@kvack.org,
	akpm@linux-foundation.org
Subject: Re: [PATCHSET v5 0/12] Add support for async buffered reads
Date: Mon, 1 Jun 2020 08:04:38 -0600	[thread overview]
Message-ID: <cdb3ac15-0c41-6147-35f1-41b2a3be1c33@kernel.dk> (raw)
In-Reply-To: <CA+icZUXkWG=08rz9Lp1-ZaRCs+GMTwEiUaFLze9xpL2SpZbdsQ@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 355 bytes --]

On 6/1/20 7:35 AM, Sedat Dilek wrote:
> Hi Jens,
> 
> with Linux v5.7 final I switched to linux-block.git/for-next and reverted...
> 
> "block: read-ahead submission should imply no-wait as well"
> 
> ...and see no boot-slowdowns.

Can you try with these patches applied instead? Or pull my async-readahead
branch from the same location.

-- 
Jens Axboe


[-- Attachment #2: 0006-Revert-block-read-ahead-submission-should-imply-no-w.patch --]
[-- Type: text/x-patch, Size: 1014 bytes --]

From 297f4d794780f7f55180fb0de6692bd1a1d81c58 Mon Sep 17 00:00:00 2001
From: Jens Axboe <axboe@kernel.dk>
Date: Sun, 31 May 2020 21:31:08 -0600
Subject: [PATCH 6/6] Revert "block: read-ahead submission should imply no-wait
 as well"

This reverts commit 381000ebbf4fed96c206571a04511c0667e38e18.
---
 include/linux/blk_types.h | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h
index c296463c15eb..ccb895f911b1 100644
--- a/include/linux/blk_types.h
+++ b/include/linux/blk_types.h
@@ -374,8 +374,7 @@ enum req_flag_bits {
 #define REQ_INTEGRITY		(1ULL << __REQ_INTEGRITY)
 #define REQ_FUA			(1ULL << __REQ_FUA)
 #define REQ_PREFLUSH		(1ULL << __REQ_PREFLUSH)
-#define REQ_RAHEAD		\
-	((1ULL << __REQ_RAHEAD) | (1ULL << __REQ_NOWAIT))
+#define REQ_RAHEAD		(1ULL << __REQ_RAHEAD)
 #define REQ_BACKGROUND		(1ULL << __REQ_BACKGROUND)
 #define REQ_NOWAIT		(1ULL << __REQ_NOWAIT)
 #define REQ_CGROUP_PUNT		(1ULL << __REQ_CGROUP_PUNT)
-- 
2.26.2


[-- Attachment #3: 0005-fs-make-mpage_readpages-take-a-struct-kiocb-argument.patch --]
[-- Type: text/x-patch, Size: 10724 bytes --]

From ffbf3c623a4835c388296d52d82ee7abe75535cf Mon Sep 17 00:00:00 2001
From: Jens Axboe <axboe@kernel.dk>
Date: Sun, 31 May 2020 20:53:26 -0600
Subject: [PATCH 5/6] fs: make mpage_readpages() take a struct kiocb argument

The callers already have it, so just pass it in. Have mpage_readpages()
set REQ_NOWAIT, if IOCB_NOWAIT is set in the iocb.

Signed-off-by: Jens Axboe <axboe@kernel.dk>
---
 fs/block_dev.c        |  2 +-
 fs/exfat/inode.c      |  2 +-
 fs/ext2/inode.c       |  2 +-
 fs/fat/inode.c        |  2 +-
 fs/gfs2/aops.c        |  2 +-
 fs/hpfs/file.c        |  2 +-
 fs/isofs/inode.c      |  2 +-
 fs/jfs/inode.c        |  2 +-
 fs/mpage.c            | 17 +++++++++++++----
 fs/nilfs2/inode.c     |  2 +-
 fs/ocfs2/aops.c       |  2 +-
 fs/omfs/file.c        |  2 +-
 fs/qnx6/inode.c       |  2 +-
 fs/reiserfs/inode.c   |  2 +-
 fs/udf/inode.c        |  2 +-
 include/linux/mpage.h |  5 +++--
 16 files changed, 30 insertions(+), 20 deletions(-)

diff --git a/fs/block_dev.c b/fs/block_dev.c
index 87a540b42fa7..bbc1bd8078d6 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -617,7 +617,7 @@ static int blkdev_readpage(struct file * file, struct page * page)
 static int blkdev_readpages(struct kiocb *kiocb, struct address_space *mapping,
 			struct list_head *pages, unsigned nr_pages)
 {
-	return mpage_readpages(mapping, pages, nr_pages, blkdev_get_block);
+	return mpage_readpages(mapping, kiocb, pages, nr_pages, blkdev_get_block);
 }
 
 static int blkdev_write_begin(struct file *file, struct address_space *mapping,
diff --git a/fs/exfat/inode.c b/fs/exfat/inode.c
index 9905307dfba2..a7757edf5534 100644
--- a/fs/exfat/inode.c
+++ b/fs/exfat/inode.c
@@ -375,7 +375,7 @@ static int exfat_readpage(struct file *file, struct page *page)
 static int exfat_readpages(struct kiocb *kiocb, struct address_space *mapping,
 		struct list_head *pages, unsigned int nr_pages)
 {
-	return mpage_readpages(mapping, pages, nr_pages, exfat_get_block);
+	return mpage_readpages(mapping, kiocb, pages, nr_pages, exfat_get_block);
 }
 
 static int exfat_writepage(struct page *page, struct writeback_control *wbc)
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
index 3843900d6251..706fc2628a3a 100644
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -881,7 +881,7 @@ static int
 ext2_readpages(struct kiocb *kiocb, struct address_space *mapping,
 		struct list_head *pages, unsigned nr_pages)
 {
-	return mpage_readpages(mapping, pages, nr_pages, ext2_get_block);
+	return mpage_readpages(mapping, kiocb, pages, nr_pages, ext2_get_block);
 }
 
 static int
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index ab9dfcbf1bd3..3c47485d7f83 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -213,7 +213,7 @@ static int fat_readpage(struct file *file, struct page *page)
 static int fat_readpages(struct kiocb *kiocb, struct address_space *mapping,
 			 struct list_head *pages, unsigned nr_pages)
 {
-	return mpage_readpages(mapping, pages, nr_pages, fat_get_block);
+	return mpage_readpages(mapping, kiocb, pages, nr_pages, fat_get_block);
 }
 
 static void fat_write_failed(struct address_space *mapping, loff_t to)
diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c
index 37d18f82e5a1..3e26ca463ca3 100644
--- a/fs/gfs2/aops.c
+++ b/fs/gfs2/aops.c
@@ -608,7 +608,7 @@ static int gfs2_readpages(struct kiocb *kiocb, struct address_space *mapping,
 	if (unlikely(ret))
 		goto out_uninit;
 	if (!gfs2_is_stuffed(ip))
-		ret = mpage_readpages(mapping, pages, nr_pages, gfs2_block_map);
+		ret = mpage_readpages(mapping, kiocb, pages, nr_pages, gfs2_block_map);
 	gfs2_glock_dq(&gh);
 out_uninit:
 	gfs2_holder_uninit(&gh);
diff --git a/fs/hpfs/file.c b/fs/hpfs/file.c
index 5b9c537d011c..21df02964219 100644
--- a/fs/hpfs/file.c
+++ b/fs/hpfs/file.c
@@ -128,7 +128,7 @@ static int hpfs_writepage(struct page *page, struct writeback_control *wbc)
 static int hpfs_readpages(struct kiocb *kiocb, struct address_space *mapping,
 			  struct list_head *pages, unsigned nr_pages)
 {
-	return mpage_readpages(mapping, pages, nr_pages, hpfs_get_block);
+	return mpage_readpages(mapping, kiocb, pages, nr_pages, hpfs_get_block);
 }
 
 static int hpfs_writepages(struct address_space *mapping,
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c
index 071da59b7266..060e8dfbe1a2 100644
--- a/fs/isofs/inode.c
+++ b/fs/isofs/inode.c
@@ -1186,7 +1186,7 @@ static int isofs_readpage(struct file *file, struct page *page)
 static int isofs_readpages(struct kiocb *kiocb, struct address_space *mapping,
 			struct list_head *pages, unsigned nr_pages)
 {
-	return mpage_readpages(mapping, pages, nr_pages, isofs_get_block);
+	return mpage_readpages(mapping, kiocb, pages, nr_pages, isofs_get_block);
 }
 
 static sector_t _isofs_bmap(struct address_space *mapping, sector_t block)
diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c
index 503e2e5cb79d..569e4f4123dd 100644
--- a/fs/jfs/inode.c
+++ b/fs/jfs/inode.c
@@ -299,7 +299,7 @@ static int jfs_readpage(struct file *file, struct page *page)
 static int jfs_readpages(struct kiocb *kiocb, struct address_space *mapping,
 		struct list_head *pages, unsigned nr_pages)
 {
-	return mpage_readpages(mapping, pages, nr_pages, jfs_get_block);
+	return mpage_readpages(mapping, kiocb, pages, nr_pages, jfs_get_block);
 }
 
 static void jfs_write_failed(struct address_space *mapping, loff_t to)
diff --git a/fs/mpage.c b/fs/mpage.c
index ccba3c4c4479..9148d1eae8ff 100644
--- a/fs/mpage.c
+++ b/fs/mpage.c
@@ -138,6 +138,7 @@ struct mpage_readpage_args {
 	struct page *page;
 	unsigned int nr_pages;
 	bool is_readahead;
+	bool nowait;
 	sector_t last_block_in_bio;
 	struct buffer_head map_bh;
 	unsigned long first_logical_block;
@@ -182,6 +183,8 @@ static struct bio *do_mpage_readpage(struct mpage_readpage_args *args)
 		op_flags = 0;
 		gfp = mapping_gfp_constraint(page->mapping, GFP_KERNEL);
 	}
+	if (args->nowait)
+		op_flags |= REQ_NOWAIT;
 
 	if (page_has_buffers(page))
 		goto confused;
@@ -382,12 +385,14 @@ static struct bio *do_mpage_readpage(struct mpage_readpage_args *args)
  * This all causes the disk requests to be issued in the correct order.
  */
 int
-mpage_readpages(struct address_space *mapping, struct list_head *pages,
-				unsigned nr_pages, get_block_t get_block)
+mpage_readpages(struct address_space *mapping, struct kiocb *kiocb,
+		struct list_head *pages, unsigned nr_pages,
+		get_block_t get_block)
 {
 	struct mpage_readpage_args args = {
 		.get_block = get_block,
 		.is_readahead = true,
+		.nowait = kiocb->ki_flags & IOCB_NOWAIT,
 	};
 	unsigned page_idx;
 
@@ -406,8 +411,12 @@ mpage_readpages(struct address_space *mapping, struct list_head *pages,
 		put_page(page);
 	}
 	BUG_ON(!list_empty(pages));
-	if (args.bio)
-		mpage_bio_submit(REQ_OP_READ, REQ_RAHEAD, args.bio);
+	if (args.bio) {
+		int op = REQ_RAHEAD;
+		if (args.nowait)
+			op |= REQ_NOWAIT;
+		mpage_bio_submit(REQ_OP_READ, op, args.bio);
+	}
 	return 0;
 }
 EXPORT_SYMBOL(mpage_readpages);
diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c
index a981c9404fbc..3cbc8b7284a4 100644
--- a/fs/nilfs2/inode.c
+++ b/fs/nilfs2/inode.c
@@ -156,7 +156,7 @@ static int nilfs_readpage(struct file *file, struct page *page)
 static int nilfs_readpages(struct kiocb *kiocb, struct address_space *mapping,
 			   struct list_head *pages, unsigned int nr_pages)
 {
-	return mpage_readpages(mapping, pages, nr_pages, nilfs_get_block);
+	return mpage_readpages(mapping, kiocb, pages, nr_pages, nilfs_get_block);
 }
 
 static int nilfs_writepages(struct address_space *mapping,
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index aa54b0d0d4a1..50ed84f53b20 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -388,7 +388,7 @@ static int ocfs2_readpages(struct kiocb *kiocb, struct address_space *mapping,
 	if (start >= i_size_read(inode))
 		goto out_unlock;
 
-	err = mpage_readpages(mapping, pages, nr_pages, ocfs2_get_block);
+	err = mpage_readpages(mapping, kiocb, pages, nr_pages, ocfs2_get_block);
 
 out_unlock:
 	up_read(&oi->ip_alloc_sem);
diff --git a/fs/omfs/file.c b/fs/omfs/file.c
index 195bb390ba24..384e8c99fc4f 100644
--- a/fs/omfs/file.c
+++ b/fs/omfs/file.c
@@ -292,7 +292,7 @@ static int omfs_readpage(struct file *file, struct page *page)
 static int omfs_readpages(struct kiocb *kiocb, struct address_space *mapping,
 		struct list_head *pages, unsigned nr_pages)
 {
-	return mpage_readpages(mapping, pages, nr_pages, omfs_get_block);
+	return mpage_readpages(mapping, kiocb, pages, nr_pages, omfs_get_block);
 }
 
 static int omfs_writepage(struct page *page, struct writeback_control *wbc)
diff --git a/fs/qnx6/inode.c b/fs/qnx6/inode.c
index c964fd63d4a5..ef603636ca2d 100644
--- a/fs/qnx6/inode.c
+++ b/fs/qnx6/inode.c
@@ -102,7 +102,7 @@ static int qnx6_readpage(struct file *file, struct page *page)
 static int qnx6_readpages(struct kiocb *kiocb, struct address_space *mapping,
 		   struct list_head *pages, unsigned nr_pages)
 {
-	return mpage_readpages(mapping, pages, nr_pages, qnx6_get_block);
+	return mpage_readpages(mapping, kiocb, pages, nr_pages, qnx6_get_block);
 }
 
 /*
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
index 01d5ccdaa5b4..50c93c526557 100644
--- a/fs/reiserfs/inode.c
+++ b/fs/reiserfs/inode.c
@@ -1164,7 +1164,7 @@ static int
 reiserfs_readpages(struct kiocb *kiocb, struct address_space *mapping,
 		   struct list_head *pages, unsigned nr_pages)
 {
-	return mpage_readpages(mapping, pages, nr_pages, reiserfs_get_block);
+	return mpage_readpages(mapping, kiocb, pages, nr_pages, reiserfs_get_block);
 }
 
 /*
diff --git a/fs/udf/inode.c b/fs/udf/inode.c
index c541ca95f851..c45d4da5e707 100644
--- a/fs/udf/inode.c
+++ b/fs/udf/inode.c
@@ -198,7 +198,7 @@ static int udf_readpage(struct file *file, struct page *page)
 static int udf_readpages(struct kiocb *kiocb, struct address_space *mapping,
 			struct list_head *pages, unsigned nr_pages)
 {
-	return mpage_readpages(mapping, pages, nr_pages, udf_get_block);
+	return mpage_readpages(mapping, kiocb, pages, nr_pages, udf_get_block);
 }
 
 static int udf_write_begin(struct file *file, struct address_space *mapping,
diff --git a/include/linux/mpage.h b/include/linux/mpage.h
index 001f1fcf9836..f708c7a442ae 100644
--- a/include/linux/mpage.h
+++ b/include/linux/mpage.h
@@ -14,8 +14,9 @@
 
 struct writeback_control;
 
-int mpage_readpages(struct address_space *mapping, struct list_head *pages,
-				unsigned nr_pages, get_block_t get_block);
+int mpage_readpages(struct address_space *mapping, struct kiocb *kiocb,
+			struct list_head *pages, unsigned nr_pages,
+			get_block_t get_block);
 int mpage_readpage(struct page *page, get_block_t get_block);
 int mpage_writepages(struct address_space *mapping,
 		struct writeback_control *wbc, get_block_t get_block);
-- 
2.26.2


[-- Attachment #4: 0004-iomap-set-REQ_NOWAIT-on-bio-if-IOCB_NOWAIT-is-set-in.patch --]
[-- Type: text/x-patch, Size: 3773 bytes --]

From d17311d78f5d5ffa73cbdd5cbf925d0a4188807d Mon Sep 17 00:00:00 2001
From: Jens Axboe <axboe@kernel.dk>
Date: Sun, 31 May 2020 20:44:18 -0600
Subject: [PATCH 4/6] iomap: set REQ_NOWAIT on bio if IOCB_NOWAIT is set in
 kiocb

Signed-off-by: Jens Axboe <axboe@kernel.dk>
---
 fs/iomap/buffered-io.c | 9 +++++++--
 fs/xfs/xfs_aops.c      | 3 ++-
 fs/zonefs/super.c      | 5 +++--
 include/linux/iomap.h  | 5 +++--
 4 files changed, 15 insertions(+), 7 deletions(-)

diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c
index 89e21961d1ad..4558b455182f 100644
--- a/fs/iomap/buffered-io.c
+++ b/fs/iomap/buffered-io.c
@@ -215,6 +215,7 @@ struct iomap_readpage_ctx {
 	struct page		*cur_page;
 	bool			cur_page_in_bio;
 	bool			is_readahead;
+	bool			nowait;
 	struct bio		*bio;
 	struct list_head	*pages;
 };
@@ -321,6 +322,8 @@ iomap_readpage_actor(struct inode *inode, loff_t pos, loff_t length, void *data,
 		ctx->bio->bi_opf = REQ_OP_READ;
 		if (ctx->is_readahead)
 			ctx->bio->bi_opf |= REQ_RAHEAD;
+		if (ctx->nowait)
+			ctx->bio->bi_opf |= REQ_NOWAIT;
 		ctx->bio->bi_iter.bi_sector = sector;
 		bio_set_dev(ctx->bio, iomap->bdev);
 		ctx->bio->bi_end_io = iomap_read_end_io;
@@ -432,12 +435,14 @@ iomap_readpages_actor(struct inode *inode, loff_t pos, loff_t length,
 }
 
 int
-iomap_readpages(struct address_space *mapping, struct list_head *pages,
-		unsigned nr_pages, const struct iomap_ops *ops)
+iomap_readpages(struct address_space *mapping, struct kiocb *kiocb,
+		struct list_head *pages, unsigned nr_pages,
+		const struct iomap_ops *ops)
 {
 	struct iomap_readpage_ctx ctx = {
 		.pages		= pages,
 		.is_readahead	= true,
+		.nowait		= kiocb->ki_flags & IOCB_NOWAIT,
 	};
 	loff_t pos = page_offset(list_entry(pages->prev, struct page, lru));
 	loff_t last = page_offset(list_entry(pages->next, struct page, lru));
diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c
index bff9a2374ece..bc8ea7cd1441 100644
--- a/fs/xfs/xfs_aops.c
+++ b/fs/xfs/xfs_aops.c
@@ -628,7 +628,8 @@ xfs_vm_readpages(
 	struct list_head	*pages,
 	unsigned		nr_pages)
 {
-	return iomap_readpages(mapping, pages, nr_pages, &xfs_read_iomap_ops);
+	return iomap_readpages(mapping, kiocb, pages, nr_pages,
+				&xfs_read_iomap_ops);
 }
 
 static int
diff --git a/fs/zonefs/super.c b/fs/zonefs/super.c
index 11812841a5fa..06b4f621a14a 100644
--- a/fs/zonefs/super.c
+++ b/fs/zonefs/super.c
@@ -79,10 +79,11 @@ static int zonefs_readpage(struct file *unused, struct page *page)
 	return iomap_readpage(page, &zonefs_iomap_ops);
 }
 
-static int zonefs_readpages(struct kiocb *unused, struct address_space *mapping,
+static int zonefs_readpages(struct kiocb *kiocb, struct address_space *mapping,
 			    struct list_head *pages, unsigned int nr_pages)
 {
-	return iomap_readpages(mapping, pages, nr_pages, &zonefs_iomap_ops);
+	return iomap_readpages(mapping, kiocb, pages, nr_pages,
+				&zonefs_iomap_ops);
 }
 
 /*
diff --git a/include/linux/iomap.h b/include/linux/iomap.h
index 8b09463dae0d..6b5d802d7227 100644
--- a/include/linux/iomap.h
+++ b/include/linux/iomap.h
@@ -155,8 +155,9 @@ loff_t iomap_apply(struct inode *inode, loff_t pos, loff_t length,
 ssize_t iomap_file_buffered_write(struct kiocb *iocb, struct iov_iter *from,
 		const struct iomap_ops *ops);
 int iomap_readpage(struct page *page, const struct iomap_ops *ops);
-int iomap_readpages(struct address_space *mapping, struct list_head *pages,
-		unsigned nr_pages, const struct iomap_ops *ops);
+int iomap_readpages(struct address_space *mapping, struct kiocb *kiocb,
+		struct list_head *pages, unsigned nr_pages,
+		const struct iomap_ops *ops);
 int iomap_set_page_dirty(struct page *page);
 int iomap_is_partially_uptodate(struct page *page, unsigned long from,
 		unsigned long count);
-- 
2.26.2


[-- Attachment #5: 0003-mm-make-generic_file_buffered_read-use-iocb-read-ahe.patch --]
[-- Type: text/x-patch, Size: 1189 bytes --]

From 3a7284cf4ef7c762ac21ffb9644c04346f0f4a59 Mon Sep 17 00:00:00 2001
From: Jens Axboe <axboe@kernel.dk>
Date: Sun, 31 May 2020 20:26:34 -0600
Subject: [PATCH 3/6] mm: make generic_file_buffered_read() use iocb read-ahead
 helpers

Signed-off-by: Jens Axboe <axboe@kernel.dk>
---
 mm/filemap.c | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/mm/filemap.c b/mm/filemap.c
index abdd3f32c932..eea40b5894fb 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -2053,17 +2053,16 @@ static ssize_t generic_file_buffered_read(struct kiocb *iocb,
 
 		page = find_get_page(mapping, index);
 		if (!page) {
-			page_cache_sync_readahead(mapping,
-					ra, filp,
-					index, last_index - index);
+			__page_cache_sync_readahead(mapping, ra, iocb, index,
+							last_index - index);
 			page = find_get_page(mapping, index);
 			if (unlikely(page == NULL))
 				goto no_cached_page;
 		}
 		if (PageReadahead(page)) {
-			page_cache_async_readahead(mapping,
-					ra, filp, page,
-					index, last_index - index);
+			__page_cache_async_readahead(mapping, ra, iocb, page,
+							index,
+							last_index - index);
 		}
 		if (!PageUptodate(page)) {
 			/*
-- 
2.26.2


[-- Attachment #6: 0002-mm-provide-read-ahead-helpers-that-take-a-struct-kio.patch --]
[-- Type: text/x-patch, Size: 4030 bytes --]

From 72dfe63dd44979d182be741d2446d364546c5df5 Mon Sep 17 00:00:00 2001
From: Jens Axboe <axboe@kernel.dk>
Date: Sun, 31 May 2020 20:25:04 -0600
Subject: [PATCH 2/6] mm: provide read-ahead helpers that take a struct kiocb

Signed-off-by: Jens Axboe <axboe@kernel.dk>
---
 mm/internal.h  | 10 +++++++
 mm/readahead.c | 79 +++++++++++++++++++++++++++++++-------------------
 2 files changed, 59 insertions(+), 30 deletions(-)

diff --git a/mm/internal.h b/mm/internal.h
index 1d051cbadf1a..c486d675af41 100644
--- a/mm/internal.h
+++ b/mm/internal.h
@@ -63,6 +63,16 @@ static inline unsigned long ra_submit(struct file_ra_state *ra,
 					ra->start, ra->size, ra->async_size);
 }
 
+void __page_cache_sync_readahead(struct address_space *mapping,
+				 struct file_ra_state *ra,
+				 struct kiocb *kiocb,  pgoff_t offset,
+				 unsigned long req_size);
+
+void __page_cache_async_readahead(struct address_space *mapping,
+				  struct file_ra_state *ra, struct kiocb *kiocb,
+				  struct page *page, pgoff_t offset,
+				  unsigned long req_size);
+
 /**
  * page_evictable - test whether a page is evictable
  * @page: the page to test
diff --git a/mm/readahead.c b/mm/readahead.c
index 657206f6318d..54a41dae4fea 100644
--- a/mm/readahead.c
+++ b/mm/readahead.c
@@ -493,6 +493,29 @@ ondemand_readahead(struct address_space *mapping,
 	return ra_submit(ra, mapping, kiocb);
 }
 
+void __page_cache_sync_readahead(struct address_space *mapping,
+				 struct file_ra_state *ra, struct kiocb *kiocb,
+				 pgoff_t offset, unsigned long req_size)
+{
+	struct file *filp = kiocb->ki_filp;
+
+	/* no read-ahead */
+	if (!ra->ra_pages)
+		return;
+
+	if (blk_cgroup_congested())
+		return;
+
+	/* be dumb */
+	if (filp && (filp->f_mode & FMODE_RANDOM)) {
+		force_page_cache_readahead(mapping, kiocb, offset, req_size);
+		return;
+	}
+
+	/* do read-ahead */
+	ondemand_readahead(mapping, ra, kiocb, false, offset, req_size);
+}
+
 /**
  * page_cache_sync_readahead - generic file readahead
  * @mapping: address_space which holds the pagecache and I/O vectors
@@ -513,23 +536,40 @@ void page_cache_sync_readahead(struct address_space *mapping,
 {
 	struct kiocb kiocb = { .ki_filp = filp, };
 
+	__page_cache_sync_readahead(mapping, ra, &kiocb, offset, req_size);
+}
+EXPORT_SYMBOL_GPL(page_cache_sync_readahead);
+
+void
+__page_cache_async_readahead(struct address_space *mapping,
+			     struct file_ra_state *ra, struct kiocb *kiocb,
+			     struct page *page, pgoff_t offset,
+			     unsigned long req_size)
+{
 	/* no read-ahead */
 	if (!ra->ra_pages)
 		return;
 
-	if (blk_cgroup_congested())
+	/*
+	 * Same bit is used for PG_readahead and PG_reclaim.
+	 */
+	if (PageWriteback(page))
 		return;
 
-	/* be dumb */
-	if (filp && (filp->f_mode & FMODE_RANDOM)) {
-		force_page_cache_readahead(mapping, &kiocb, offset, req_size);
+	ClearPageReadahead(page);
+
+	/*
+	 * Defer asynchronous read-ahead on IO congestion.
+	 */
+	if (inode_read_congested(mapping->host))
+		return;
+
+	if (blk_cgroup_congested())
 		return;
-	}
 
 	/* do read-ahead */
-	ondemand_readahead(mapping, ra, &kiocb, false, offset, req_size);
+	ondemand_readahead(mapping, ra, kiocb, true, offset, req_size);
 }
-EXPORT_SYMBOL_GPL(page_cache_sync_readahead);
 
 /**
  * page_cache_async_readahead - file readahead for marked pages
@@ -554,29 +594,8 @@ page_cache_async_readahead(struct address_space *mapping,
 {
 	struct kiocb kiocb = { .ki_filp = filp, };
 
-	/* no read-ahead */
-	if (!ra->ra_pages)
-		return;
-
-	/*
-	 * Same bit is used for PG_readahead and PG_reclaim.
-	 */
-	if (PageWriteback(page))
-		return;
-
-	ClearPageReadahead(page);
-
-	/*
-	 * Defer asynchronous read-ahead on IO congestion.
-	 */
-	if (inode_read_congested(mapping->host))
-		return;
-
-	if (blk_cgroup_congested())
-		return;
-
-	/* do read-ahead */
-	ondemand_readahead(mapping, ra, &kiocb, true, offset, req_size);
+	__page_cache_async_readahead(mapping, ra, &kiocb, page, offset,
+					req_size);
 }
 EXPORT_SYMBOL_GPL(page_cache_async_readahead);
 
-- 
2.26.2


[-- Attachment #7: 0001-fs-make-aops-readpages-take-kiocb-argument.patch --]
[-- Type: text/x-patch, Size: 28302 bytes --]

From 707258c22fea35a5915ff0373231fb07a8a1c9eb Mon Sep 17 00:00:00 2001
From: Jens Axboe <axboe@kernel.dk>
Date: Sun, 31 May 2020 19:35:33 -0600
Subject: [PATCH 1/6] fs: make aops->readpages() take kiocb argument

Instead of passing in a file, pass in the kiocb instead. This still
provides access to the file through kiocb->ki_filp, but also provides
access to more information related to the IO. We'll be using that to
ensure that ->readpages() understands IOCB_NOWAIT.

Signed-off-by: Jens Axboe <axboe@kernel.dk>
---
 fs/9p/vfs_addr.c       |  3 ++-
 fs/afs/file.c          |  8 ++++----
 fs/block_dev.c         |  2 +-
 fs/btrfs/inode.c       |  2 +-
 fs/ceph/addr.c         |  3 ++-
 fs/cifs/file.c         |  3 ++-
 fs/erofs/data.c        |  2 +-
 fs/erofs/zdata.c       |  2 +-
 fs/exfat/inode.c       |  2 +-
 fs/ext2/inode.c        |  2 +-
 fs/ext4/inode.c        |  2 +-
 fs/f2fs/data.c         |  2 +-
 fs/fat/inode.c         |  2 +-
 fs/fuse/file.c         |  6 +++---
 fs/gfs2/aops.c         |  2 +-
 fs/hpfs/file.c         |  2 +-
 fs/isofs/inode.c       |  2 +-
 fs/jfs/inode.c         |  2 +-
 fs/nfs/read.c          |  3 ++-
 fs/nilfs2/inode.c      |  2 +-
 fs/ocfs2/aops.c        |  2 +-
 fs/omfs/file.c         |  2 +-
 fs/qnx6/inode.c        |  2 +-
 fs/reiserfs/inode.c    |  2 +-
 fs/udf/inode.c         |  2 +-
 fs/xfs/xfs_aops.c      |  2 +-
 fs/zonefs/super.c      |  2 +-
 include/linux/fs.h     |  2 +-
 include/linux/mm.h     |  6 +++---
 include/linux/nfs_fs.h |  2 +-
 mm/fadvise.c           |  7 +++++--
 mm/filemap.c           |  3 ++-
 mm/internal.h          |  6 +++---
 mm/readahead.c         | 39 ++++++++++++++++++++++-----------------
 34 files changed, 73 insertions(+), 60 deletions(-)

diff --git a/fs/9p/vfs_addr.c b/fs/9p/vfs_addr.c
index cce9ace651a2..f2980829bb9f 100644
--- a/fs/9p/vfs_addr.c
+++ b/fs/9p/vfs_addr.c
@@ -95,9 +95,10 @@ static int v9fs_vfs_readpage(struct file *filp, struct page *page)
  *
  */
 
-static int v9fs_vfs_readpages(struct file *filp, struct address_space *mapping,
+static int v9fs_vfs_readpages(struct kiocb *kiocb, struct address_space *mapping,
 			     struct list_head *pages, unsigned nr_pages)
 {
+	struct file *filp = kiocb->ki_filp;
 	int ret = 0;
 	struct inode *inode;
 
diff --git a/fs/afs/file.c b/fs/afs/file.c
index 8415733f7bc1..447b6524c2e9 100644
--- a/fs/afs/file.c
+++ b/fs/afs/file.c
@@ -22,7 +22,7 @@ static void afs_invalidatepage(struct page *page, unsigned int offset,
 			       unsigned int length);
 static int afs_releasepage(struct page *page, gfp_t gfp_flags);
 
-static int afs_readpages(struct file *filp, struct address_space *mapping,
+static int afs_readpages(struct kiocb *kiocb, struct address_space *mapping,
 			 struct list_head *pages, unsigned nr_pages);
 
 const struct file_operations afs_file_operations = {
@@ -538,10 +538,10 @@ static int afs_readpages_one(struct file *file, struct address_space *mapping,
 /*
  * read a set of pages
  */
-static int afs_readpages(struct file *file, struct address_space *mapping,
+static int afs_readpages(struct kiocb *kiocb, struct address_space *mapping,
 			 struct list_head *pages, unsigned nr_pages)
 {
-	struct key *key = afs_file_key(file);
+	struct key *key = afs_file_key(kiocb->ki_filp);
 	struct afs_vnode *vnode;
 	int ret = 0;
 
@@ -589,7 +589,7 @@ static int afs_readpages(struct file *file, struct address_space *mapping,
 	}
 
 	while (!list_empty(pages)) {
-		ret = afs_readpages_one(file, mapping, pages);
+		ret = afs_readpages_one(kiocb->ki_filp, mapping, pages);
 		if (ret < 0)
 			break;
 	}
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 980cfce01c9a..87a540b42fa7 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -614,7 +614,7 @@ static int blkdev_readpage(struct file * file, struct page * page)
 	return block_read_full_page(page, blkdev_get_block);
 }
 
-static int blkdev_readpages(struct file *file, struct address_space *mapping,
+static int blkdev_readpages(struct kiocb *kiocb, struct address_space *mapping,
 			struct list_head *pages, unsigned nr_pages)
 {
 	return mpage_readpages(mapping, pages, nr_pages, blkdev_get_block);
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 320d1062068d..1569d29fdfc4 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -8294,7 +8294,7 @@ static int btrfs_writepages(struct address_space *mapping,
 }
 
 static int
-btrfs_readpages(struct file *file, struct address_space *mapping,
+btrfs_readpages(struct kiocb *kiocb, struct address_space *mapping,
 		struct list_head *pages, unsigned nr_pages)
 {
 	return extent_readpages(mapping, pages, nr_pages);
diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c
index 6f4678d98df7..687714a29e89 100644
--- a/fs/ceph/addr.c
+++ b/fs/ceph/addr.c
@@ -477,9 +477,10 @@ static int start_read(struct inode *inode, struct ceph_rw_context *rw_ctx,
  * Read multiple pages.  Leave pages we don't read + unlock in page_list;
  * the caller (VM) cleans them up.
  */
-static int ceph_readpages(struct file *file, struct address_space *mapping,
+static int ceph_readpages(struct kiocb *kiocb, struct address_space *mapping,
 			  struct list_head *page_list, unsigned nr_pages)
 {
+	struct file *file = kiocb->ki_filp;
 	struct inode *inode = file_inode(file);
 	struct ceph_fs_client *fsc = ceph_inode_to_client(inode);
 	struct ceph_file_info *fi = file->private_data;
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 75ddce8ef456..5eec4f40811c 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -4344,11 +4344,12 @@ readpages_get_pages(struct address_space *mapping, struct list_head *page_list,
 	return rc;
 }
 
-static int cifs_readpages(struct file *file, struct address_space *mapping,
+static int cifs_readpages(struct kiocb *kiocb, struct address_space *mapping,
 	struct list_head *page_list, unsigned num_pages)
 {
 	int rc;
 	struct list_head tmplist;
+	struct file *file = kiocb->ki_filp;
 	struct cifsFileInfo *open_file = file->private_data;
 	struct cifs_sb_info *cifs_sb = CIFS_FILE_SB(file);
 	struct TCP_Server_Info *server;
diff --git a/fs/erofs/data.c b/fs/erofs/data.c
index fc3a8d8064f8..853b905a15c4 100644
--- a/fs/erofs/data.c
+++ b/fs/erofs/data.c
@@ -280,7 +280,7 @@ static int erofs_raw_access_readpage(struct file *file, struct page *page)
 	return 0;
 }
 
-static int erofs_raw_access_readpages(struct file *filp,
+static int erofs_raw_access_readpages(struct kiocb *kiocb,
 				      struct address_space *mapping,
 				      struct list_head *pages,
 				      unsigned int nr_pages)
diff --git a/fs/erofs/zdata.c b/fs/erofs/zdata.c
index c4b6c9aa87ec..bc8c02b088ce 100644
--- a/fs/erofs/zdata.c
+++ b/fs/erofs/zdata.c
@@ -1305,7 +1305,7 @@ static bool should_decompress_synchronously(struct erofs_sb_info *sbi,
 	return nr <= sbi->max_sync_decompress_pages;
 }
 
-static int z_erofs_readpages(struct file *filp, struct address_space *mapping,
+static int z_erofs_readpages(struct kiocb *kiocb, struct address_space *mapping,
 			     struct list_head *pages, unsigned int nr_pages)
 {
 	struct inode *const inode = mapping->host;
diff --git a/fs/exfat/inode.c b/fs/exfat/inode.c
index 06887492f54b..9905307dfba2 100644
--- a/fs/exfat/inode.c
+++ b/fs/exfat/inode.c
@@ -372,7 +372,7 @@ static int exfat_readpage(struct file *file, struct page *page)
 	return mpage_readpage(page, exfat_get_block);
 }
 
-static int exfat_readpages(struct file *file, struct address_space *mapping,
+static int exfat_readpages(struct kiocb *kiocb, struct address_space *mapping,
 		struct list_head *pages, unsigned int nr_pages)
 {
 	return mpage_readpages(mapping, pages, nr_pages, exfat_get_block);
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
index c885cf7d724b..3843900d6251 100644
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -878,7 +878,7 @@ static int ext2_readpage(struct file *file, struct page *page)
 }
 
 static int
-ext2_readpages(struct file *file, struct address_space *mapping,
+ext2_readpages(struct kiocb *kiocb, struct address_space *mapping,
 		struct list_head *pages, unsigned nr_pages)
 {
 	return mpage_readpages(mapping, pages, nr_pages, ext2_get_block);
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 2a4aae6acdcb..6297804d1ac2 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -3231,7 +3231,7 @@ static int ext4_readpage(struct file *file, struct page *page)
 }
 
 static int
-ext4_readpages(struct file *file, struct address_space *mapping,
+ext4_readpages(struct kiocb *kiocb, struct address_space *mapping,
 		struct list_head *pages, unsigned nr_pages)
 {
 	struct inode *inode = mapping->host;
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index cdf2f626bea7..7330aa1e2e39 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -2304,7 +2304,7 @@ static int f2fs_read_data_page(struct file *file, struct page *page)
 	return ret;
 }
 
-static int f2fs_read_data_pages(struct file *file,
+static int f2fs_read_data_pages(struct kiocb *kiocb,
 			struct address_space *mapping,
 			struct list_head *pages, unsigned nr_pages)
 {
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index 71946da84388..ab9dfcbf1bd3 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -210,7 +210,7 @@ static int fat_readpage(struct file *file, struct page *page)
 	return mpage_readpage(page, fat_get_block);
 }
 
-static int fat_readpages(struct file *file, struct address_space *mapping,
+static int fat_readpages(struct kiocb *kiocb, struct address_space *mapping,
 			 struct list_head *pages, unsigned nr_pages)
 {
 	return mpage_readpages(mapping, pages, nr_pages, fat_get_block);
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 9d67b830fb7a..ebd40681ee94 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -962,7 +962,7 @@ static int fuse_readpages_fill(void *_data, struct page *page)
 	return 0;
 }
 
-static int fuse_readpages(struct file *file, struct address_space *mapping,
+static int fuse_readpages(struct kiocb *kiocb, struct address_space *mapping,
 			  struct list_head *pages, unsigned nr_pages)
 {
 	struct inode *inode = mapping->host;
@@ -974,7 +974,7 @@ static int fuse_readpages(struct file *file, struct address_space *mapping,
 	if (is_bad_inode(inode))
 		goto out;
 
-	data.file = file;
+	data.file = kiocb->ki_filp;
 	data.inode = inode;
 	data.nr_pages = nr_pages;
 	data.max_pages = min_t(unsigned int, nr_pages, fc->max_pages);
@@ -987,7 +987,7 @@ static int fuse_readpages(struct file *file, struct address_space *mapping,
 	err = read_cache_pages(mapping, pages, fuse_readpages_fill, &data);
 	if (!err) {
 		if (data.ia->ap.num_pages)
-			fuse_send_readpages(data.ia, file);
+			fuse_send_readpages(data.ia, kiocb->ki_filp);
 		else
 			fuse_io_free(data.ia);
 	}
diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c
index 786c1ce8f030..37d18f82e5a1 100644
--- a/fs/gfs2/aops.c
+++ b/fs/gfs2/aops.c
@@ -594,7 +594,7 @@ int gfs2_internal_read(struct gfs2_inode *ip, char *buf, loff_t *pos,
  * 4. gfs2_block_map() is relied upon to set BH_Boundary in the right places.
  */
 
-static int gfs2_readpages(struct file *file, struct address_space *mapping,
+static int gfs2_readpages(struct kiocb *kiocb, struct address_space *mapping,
 			  struct list_head *pages, unsigned nr_pages)
 {
 	struct inode *inode = mapping->host;
diff --git a/fs/hpfs/file.c b/fs/hpfs/file.c
index b36abf9cb345..5b9c537d011c 100644
--- a/fs/hpfs/file.c
+++ b/fs/hpfs/file.c
@@ -125,7 +125,7 @@ static int hpfs_writepage(struct page *page, struct writeback_control *wbc)
 	return block_write_full_page(page, hpfs_get_block, wbc);
 }
 
-static int hpfs_readpages(struct file *file, struct address_space *mapping,
+static int hpfs_readpages(struct kiocb *kiocb, struct address_space *mapping,
 			  struct list_head *pages, unsigned nr_pages)
 {
 	return mpage_readpages(mapping, pages, nr_pages, hpfs_get_block);
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c
index 276107cdaaf1..071da59b7266 100644
--- a/fs/isofs/inode.c
+++ b/fs/isofs/inode.c
@@ -1183,7 +1183,7 @@ static int isofs_readpage(struct file *file, struct page *page)
 	return mpage_readpage(page, isofs_get_block);
 }
 
-static int isofs_readpages(struct file *file, struct address_space *mapping,
+static int isofs_readpages(struct kiocb *kiocb, struct address_space *mapping,
 			struct list_head *pages, unsigned nr_pages)
 {
 	return mpage_readpages(mapping, pages, nr_pages, isofs_get_block);
diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c
index 9486afcdac76..503e2e5cb79d 100644
--- a/fs/jfs/inode.c
+++ b/fs/jfs/inode.c
@@ -296,7 +296,7 @@ static int jfs_readpage(struct file *file, struct page *page)
 	return mpage_readpage(page, jfs_get_block);
 }
 
-static int jfs_readpages(struct file *file, struct address_space *mapping,
+static int jfs_readpages(struct kiocb *kiocb, struct address_space *mapping,
 		struct list_head *pages, unsigned nr_pages)
 {
 	return mpage_readpages(mapping, pages, nr_pages, jfs_get_block);
diff --git a/fs/nfs/read.c b/fs/nfs/read.c
index 13b22e898116..4719f6b67b5c 100644
--- a/fs/nfs/read.c
+++ b/fs/nfs/read.c
@@ -402,9 +402,10 @@ readpage_async_filler(void *data, struct page *page)
 	return error;
 }
 
-int nfs_readpages(struct file *filp, struct address_space *mapping,
+int nfs_readpages(struct kiocb *kiocb, struct address_space *mapping,
 		struct list_head *pages, unsigned nr_pages)
 {
+	struct file *filp = kiocb->ki_filp;
 	struct nfs_pageio_descriptor pgio;
 	struct nfs_pgio_mirror *pgm;
 	struct nfs_readdesc desc = {
diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c
index 671085512e0f..a981c9404fbc 100644
--- a/fs/nilfs2/inode.c
+++ b/fs/nilfs2/inode.c
@@ -153,7 +153,7 @@ static int nilfs_readpage(struct file *file, struct page *page)
  * @pages - the pages to be read
  * @nr_pages - number of pages to be read
  */
-static int nilfs_readpages(struct file *file, struct address_space *mapping,
+static int nilfs_readpages(struct kiocb *kiocb, struct address_space *mapping,
 			   struct list_head *pages, unsigned int nr_pages)
 {
 	return mpage_readpages(mapping, pages, nr_pages, nilfs_get_block);
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index 3a67a6518ddf..aa54b0d0d4a1 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -350,7 +350,7 @@ static int ocfs2_readpage(struct file *file, struct page *page)
  * grow out to a tree. If need be, detecting boundary extents could
  * trivially be added in a future version of ocfs2_get_block().
  */
-static int ocfs2_readpages(struct file *filp, struct address_space *mapping,
+static int ocfs2_readpages(struct kiocb *kiocb, struct address_space *mapping,
 			   struct list_head *pages, unsigned nr_pages)
 {
 	int ret, err = -EIO;
diff --git a/fs/omfs/file.c b/fs/omfs/file.c
index d640b9388238..195bb390ba24 100644
--- a/fs/omfs/file.c
+++ b/fs/omfs/file.c
@@ -289,7 +289,7 @@ static int omfs_readpage(struct file *file, struct page *page)
 	return block_read_full_page(page, omfs_get_block);
 }
 
-static int omfs_readpages(struct file *file, struct address_space *mapping,
+static int omfs_readpages(struct kiocb *kiocb, struct address_space *mapping,
 		struct list_head *pages, unsigned nr_pages)
 {
 	return mpage_readpages(mapping, pages, nr_pages, omfs_get_block);
diff --git a/fs/qnx6/inode.c b/fs/qnx6/inode.c
index 345db56c98fd..c964fd63d4a5 100644
--- a/fs/qnx6/inode.c
+++ b/fs/qnx6/inode.c
@@ -99,7 +99,7 @@ static int qnx6_readpage(struct file *file, struct page *page)
 	return mpage_readpage(page, qnx6_get_block);
 }
 
-static int qnx6_readpages(struct file *file, struct address_space *mapping,
+static int qnx6_readpages(struct kiocb *kiocb, struct address_space *mapping,
 		   struct list_head *pages, unsigned nr_pages)
 {
 	return mpage_readpages(mapping, pages, nr_pages, qnx6_get_block);
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
index 6419e6dacc39..01d5ccdaa5b4 100644
--- a/fs/reiserfs/inode.c
+++ b/fs/reiserfs/inode.c
@@ -1161,7 +1161,7 @@ int reiserfs_get_block(struct inode *inode, sector_t block,
 }
 
 static int
-reiserfs_readpages(struct file *file, struct address_space *mapping,
+reiserfs_readpages(struct kiocb *kiocb, struct address_space *mapping,
 		   struct list_head *pages, unsigned nr_pages)
 {
 	return mpage_readpages(mapping, pages, nr_pages, reiserfs_get_block);
diff --git a/fs/udf/inode.c b/fs/udf/inode.c
index e875bc5668ee..c541ca95f851 100644
--- a/fs/udf/inode.c
+++ b/fs/udf/inode.c
@@ -195,7 +195,7 @@ static int udf_readpage(struct file *file, struct page *page)
 	return mpage_readpage(page, udf_get_block);
 }
 
-static int udf_readpages(struct file *file, struct address_space *mapping,
+static int udf_readpages(struct kiocb *kiocb, struct address_space *mapping,
 			struct list_head *pages, unsigned nr_pages)
 {
 	return mpage_readpages(mapping, pages, nr_pages, udf_get_block);
diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c
index 9d9cebf18726..bff9a2374ece 100644
--- a/fs/xfs/xfs_aops.c
+++ b/fs/xfs/xfs_aops.c
@@ -623,7 +623,7 @@ xfs_vm_readpage(
 
 STATIC int
 xfs_vm_readpages(
-	struct file		*unused,
+	struct kiocb		*kiocb,
 	struct address_space	*mapping,
 	struct list_head	*pages,
 	unsigned		nr_pages)
diff --git a/fs/zonefs/super.c b/fs/zonefs/super.c
index 25afcf55aa41..11812841a5fa 100644
--- a/fs/zonefs/super.c
+++ b/fs/zonefs/super.c
@@ -79,7 +79,7 @@ static int zonefs_readpage(struct file *unused, struct page *page)
 	return iomap_readpage(page, &zonefs_iomap_ops);
 }
 
-static int zonefs_readpages(struct file *unused, struct address_space *mapping,
+static int zonefs_readpages(struct kiocb *unused, struct address_space *mapping,
 			    struct list_head *pages, unsigned int nr_pages)
 {
 	return iomap_readpages(mapping, pages, nr_pages, &zonefs_iomap_ops);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 5ffc6d236b01..cb5adf72041b 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -381,7 +381,7 @@ struct address_space_operations {
 	 * Reads in the requested pages. Unlike ->readpage(), this is
 	 * PURELY used for read-ahead!.
 	 */
-	int (*readpages)(struct file *filp, struct address_space *mapping,
+	int (*readpages)(struct kiocb *kiocb, struct address_space *mapping,
 			struct list_head *pages, unsigned nr_pages);
 
 	int (*write_begin)(struct file *, struct address_space *mapping,
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 5a323422d783..7c805a32fdc7 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -2604,18 +2604,18 @@ void task_dirty_inc(struct task_struct *tsk);
 /* readahead.c */
 #define VM_READAHEAD_PAGES	(SZ_128K / PAGE_SIZE)
 
-int force_page_cache_readahead(struct address_space *mapping, struct file *filp,
+int force_page_cache_readahead(struct address_space *mapping, struct kiocb *kiocb,
 			pgoff_t offset, unsigned long nr_to_read);
 
 void page_cache_sync_readahead(struct address_space *mapping,
 			       struct file_ra_state *ra,
-			       struct file *filp,
+			       struct file *file,
 			       pgoff_t offset,
 			       unsigned long size);
 
 void page_cache_async_readahead(struct address_space *mapping,
 				struct file_ra_state *ra,
-				struct file *filp,
+				struct file *file,
 				struct page *pg,
 				pgoff_t offset,
 				unsigned long size);
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
index 73eda45f1cfd..27c62a08f499 100644
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -550,7 +550,7 @@ nfs_have_writebacks(struct inode *inode)
  * linux/fs/nfs/read.c
  */
 extern int  nfs_readpage(struct file *, struct page *);
-extern int  nfs_readpages(struct file *, struct address_space *,
+extern int  nfs_readpages(struct kiocb *, struct address_space *,
 		struct list_head *, unsigned);
 extern int  nfs_readpage_async(struct nfs_open_context *, struct inode *,
 			       struct page *);
diff --git a/mm/fadvise.c b/mm/fadvise.c
index 4f17c83db575..58654fd13486 100644
--- a/mm/fadvise.c
+++ b/mm/fadvise.c
@@ -92,7 +92,9 @@ int generic_fadvise(struct file *file, loff_t offset, loff_t len, int advice)
 		file->f_mode &= ~FMODE_RANDOM;
 		spin_unlock(&file->f_lock);
 		break;
-	case POSIX_FADV_WILLNEED:
+	case POSIX_FADV_WILLNEED: {
+		struct kiocb kiocb = { .ki_filp = file, };
+
 		/* First and last PARTIAL page! */
 		start_index = offset >> PAGE_SHIFT;
 		end_index = endbyte >> PAGE_SHIFT;
@@ -106,8 +108,9 @@ int generic_fadvise(struct file *file, loff_t offset, loff_t len, int advice)
 		 * Ignore return value because fadvise() shall return
 		 * success even if filesystem can't retrieve a hint,
 		 */
-		force_page_cache_readahead(mapping, file, start_index, nrpages);
+		force_page_cache_readahead(mapping, &kiocb, start_index, nrpages);
 		break;
+		}
 	case POSIX_FADV_NOREUSE:
 		break;
 	case POSIX_FADV_DONTNEED:
diff --git a/mm/filemap.c b/mm/filemap.c
index 18022de7dc33..abdd3f32c932 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -2403,6 +2403,7 @@ static struct file *do_sync_mmap_readahead(struct vm_fault *vmf)
 	struct address_space *mapping = file->f_mapping;
 	struct file *fpin = NULL;
 	pgoff_t offset = vmf->pgoff;
+	struct kiocb kiocb = { .ki_filp = file, };
 
 	/* If we don't want any read-ahead, don't bother */
 	if (vmf->vma->vm_flags & VM_RAND_READ)
@@ -2435,7 +2436,7 @@ static struct file *do_sync_mmap_readahead(struct vm_fault *vmf)
 	ra->start = max_t(long, 0, offset - ra->ra_pages / 2);
 	ra->size = ra->ra_pages;
 	ra->async_size = ra->ra_pages / 4;
-	ra_submit(ra, mapping, file);
+	ra_submit(ra, mapping, &kiocb);
 	return fpin;
 }
 
diff --git a/mm/internal.h b/mm/internal.h
index b5634e78f01d..1d051cbadf1a 100644
--- a/mm/internal.h
+++ b/mm/internal.h
@@ -50,16 +50,16 @@ void unmap_page_range(struct mmu_gather *tlb,
 			     struct zap_details *details);
 
 extern unsigned int __do_page_cache_readahead(struct address_space *mapping,
-		struct file *filp, pgoff_t offset, unsigned long nr_to_read,
+		struct kiocb *kiocb, pgoff_t offset, unsigned long nr_to_read,
 		unsigned long lookahead_size);
 
 /*
  * Submit IO for the read-ahead request in file_ra_state.
  */
 static inline unsigned long ra_submit(struct file_ra_state *ra,
-		struct address_space *mapping, struct file *filp)
+		struct address_space *mapping, struct kiocb *kiocb)
 {
-	return __do_page_cache_readahead(mapping, filp,
+	return __do_page_cache_readahead(mapping, kiocb,
 					ra->start, ra->size, ra->async_size);
 }
 
diff --git a/mm/readahead.c b/mm/readahead.c
index 2fe72cd29b47..657206f6318d 100644
--- a/mm/readahead.c
+++ b/mm/readahead.c
@@ -113,7 +113,7 @@ int read_cache_pages(struct address_space *mapping, struct list_head *pages,
 
 EXPORT_SYMBOL(read_cache_pages);
 
-static int read_pages(struct address_space *mapping, struct file *filp,
+static int read_pages(struct address_space *mapping, struct kiocb *kiocb,
 		struct list_head *pages, unsigned int nr_pages, gfp_t gfp)
 {
 	struct blk_plug plug;
@@ -123,7 +123,7 @@ static int read_pages(struct address_space *mapping, struct file *filp,
 	blk_start_plug(&plug);
 
 	if (mapping->a_ops->readpages) {
-		ret = mapping->a_ops->readpages(filp, mapping, pages, nr_pages);
+		ret = mapping->a_ops->readpages(kiocb, mapping, pages, nr_pages);
 		/* Clean up the remaining pages */
 		put_pages_list(pages);
 		goto out;
@@ -133,7 +133,7 @@ static int read_pages(struct address_space *mapping, struct file *filp,
 		struct page *page = lru_to_page(pages);
 		list_del(&page->lru);
 		if (!add_to_page_cache_lru(page, mapping, page->index, gfp))
-			mapping->a_ops->readpage(filp, page);
+			mapping->a_ops->readpage(kiocb->ki_filp, page);
 		put_page(page);
 	}
 	ret = 0;
@@ -153,7 +153,7 @@ static int read_pages(struct address_space *mapping, struct file *filp,
  * Returns the number of pages requested, or the maximum amount of I/O allowed.
  */
 unsigned int __do_page_cache_readahead(struct address_space *mapping,
-		struct file *filp, pgoff_t offset, unsigned long nr_to_read,
+		struct kiocb *kiocb, pgoff_t offset, unsigned long nr_to_read,
 		unsigned long lookahead_size)
 {
 	struct inode *inode = mapping->host;
@@ -187,7 +187,7 @@ unsigned int __do_page_cache_readahead(struct address_space *mapping,
 			 * batch.
 			 */
 			if (nr_pages)
-				read_pages(mapping, filp, &page_pool, nr_pages,
+				read_pages(mapping, kiocb, &page_pool, nr_pages,
 						gfp_mask);
 			nr_pages = 0;
 			continue;
@@ -209,7 +209,7 @@ unsigned int __do_page_cache_readahead(struct address_space *mapping,
 	 * will then handle the error.
 	 */
 	if (nr_pages)
-		read_pages(mapping, filp, &page_pool, nr_pages, gfp_mask);
+		read_pages(mapping, kiocb, &page_pool, nr_pages, gfp_mask);
 	BUG_ON(!list_empty(&page_pool));
 out:
 	return nr_pages;
@@ -219,11 +219,12 @@ unsigned int __do_page_cache_readahead(struct address_space *mapping,
  * Chunk the readahead into 2 megabyte units, so that we don't pin too much
  * memory at once.
  */
-int force_page_cache_readahead(struct address_space *mapping, struct file *filp,
-			       pgoff_t offset, unsigned long nr_to_read)
+int force_page_cache_readahead(struct address_space *mapping,
+			       struct kiocb *kiocb, pgoff_t offset,
+			       unsigned long nr_to_read)
 {
 	struct backing_dev_info *bdi = inode_to_bdi(mapping->host);
-	struct file_ra_state *ra = &filp->f_ra;
+	struct file_ra_state *ra = &kiocb->ki_filp->f_ra;
 	unsigned long max_pages;
 
 	if (unlikely(!mapping->a_ops->readpage && !mapping->a_ops->readpages))
@@ -240,7 +241,7 @@ int force_page_cache_readahead(struct address_space *mapping, struct file *filp,
 
 		if (this_chunk > nr_to_read)
 			this_chunk = nr_to_read;
-		__do_page_cache_readahead(mapping, filp, offset, this_chunk, 0);
+		__do_page_cache_readahead(mapping, kiocb, offset, this_chunk, 0);
 
 		offset += this_chunk;
 		nr_to_read -= this_chunk;
@@ -380,7 +381,7 @@ static int try_context_readahead(struct address_space *mapping,
  */
 static unsigned long
 ondemand_readahead(struct address_space *mapping,
-		   struct file_ra_state *ra, struct file *filp,
+		   struct file_ra_state *ra, struct kiocb *kiocb,
 		   bool hit_readahead_marker, pgoff_t offset,
 		   unsigned long req_size)
 {
@@ -464,7 +465,7 @@ ondemand_readahead(struct address_space *mapping,
 	 * standalone, small random read
 	 * Read as is, and do not pollute the readahead state.
 	 */
-	return __do_page_cache_readahead(mapping, filp, offset, req_size, 0);
+	return __do_page_cache_readahead(mapping, kiocb, offset, req_size, 0);
 
 initial_readahead:
 	ra->start = offset;
@@ -489,14 +490,14 @@ ondemand_readahead(struct address_space *mapping,
 		}
 	}
 
-	return ra_submit(ra, mapping, filp);
+	return ra_submit(ra, mapping, kiocb);
 }
 
 /**
  * page_cache_sync_readahead - generic file readahead
  * @mapping: address_space which holds the pagecache and I/O vectors
  * @ra: file_ra_state which holds the readahead state
- * @filp: passed on to ->readpage() and ->readpages()
+ * @kiocb: passed on to ->readpage() and ->readpages()
  * @offset: start offset into @mapping, in pagecache page-sized units
  * @req_size: hint: total size of the read which the caller is performing in
  *            pagecache pages
@@ -510,6 +511,8 @@ void page_cache_sync_readahead(struct address_space *mapping,
 			       struct file_ra_state *ra, struct file *filp,
 			       pgoff_t offset, unsigned long req_size)
 {
+	struct kiocb kiocb = { .ki_filp = filp, };
+
 	/* no read-ahead */
 	if (!ra->ra_pages)
 		return;
@@ -519,12 +522,12 @@ void page_cache_sync_readahead(struct address_space *mapping,
 
 	/* be dumb */
 	if (filp && (filp->f_mode & FMODE_RANDOM)) {
-		force_page_cache_readahead(mapping, filp, offset, req_size);
+		force_page_cache_readahead(mapping, &kiocb, offset, req_size);
 		return;
 	}
 
 	/* do read-ahead */
-	ondemand_readahead(mapping, ra, filp, false, offset, req_size);
+	ondemand_readahead(mapping, ra, &kiocb, false, offset, req_size);
 }
 EXPORT_SYMBOL_GPL(page_cache_sync_readahead);
 
@@ -549,6 +552,8 @@ page_cache_async_readahead(struct address_space *mapping,
 			   struct page *page, pgoff_t offset,
 			   unsigned long req_size)
 {
+	struct kiocb kiocb = { .ki_filp = filp, };
+
 	/* no read-ahead */
 	if (!ra->ra_pages)
 		return;
@@ -571,7 +576,7 @@ page_cache_async_readahead(struct address_space *mapping,
 		return;
 
 	/* do read-ahead */
-	ondemand_readahead(mapping, ra, filp, true, offset, req_size);
+	ondemand_readahead(mapping, ra, &kiocb, true, offset, req_size);
 }
 EXPORT_SYMBOL_GPL(page_cache_async_readahead);
 
-- 
2.26.2


  reply	other threads:[~2020-06-01 14:04 UTC|newest]

Thread overview: 81+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-05-26 19:51 [PATCHSET v5 0/12] Add support for async buffered reads Jens Axboe
2020-05-26 19:51 ` [PATCH 01/12] block: read-ahead submission should imply no-wait as well Jens Axboe
2020-05-26 19:51 ` [PATCH 02/12] mm: allow read-ahead with IOCB_NOWAIT set Jens Axboe
2020-05-26 20:45   ` Johannes Weiner
2020-05-26 19:51 ` [PATCH 03/12] mm: abstract out wake_page_match() from wake_page_function() Jens Axboe
2020-05-26 21:02   ` Johannes Weiner
2020-06-01 14:16   ` Matthew Wilcox
2020-05-26 19:51 ` [PATCH 04/12] mm: add support for async page locking Jens Axboe
2020-05-26 21:59   ` Johannes Weiner
2020-05-26 22:01     ` Jens Axboe
2020-05-27 16:02       ` Johannes Weiner
2020-06-01 14:26   ` Matthew Wilcox
2020-06-01 17:15     ` Jens Axboe
2020-05-26 19:51 ` [PATCH 05/12] mm: support async buffered reads in generic_file_buffered_read() Jens Axboe
2020-05-26 22:00   ` Johannes Weiner
2020-05-26 19:51 ` [PATCH 06/12] fs: add FMODE_BUF_RASYNC Jens Axboe
2020-05-26 19:51 ` [PATCH 07/12] ext4: flag as supporting buffered async reads Jens Axboe
2020-05-26 19:51 ` [PATCH 08/12] block: flag block devices as supporting IOCB_WAITQ Jens Axboe
2020-05-26 19:51 ` [PATCH 09/12] xfs: flag files as supporting buffered async reads Jens Axboe
2020-05-28 17:53   ` Darrick J. Wong
2020-05-28 19:23     ` Jens Axboe
2020-05-26 19:51 ` [PATCH 10/12] btrfs: " Jens Axboe
2020-05-26 19:57   ` Chris Mason
2020-05-26 19:51 ` [PATCH 11/12] mm: add kiocb_wait_page_queue_init() helper Jens Axboe
2020-05-26 22:01   ` Johannes Weiner
2020-05-26 19:51 ` [PATCH 12/12] io_uring: support true async buffered reads, if file provides it Jens Axboe
2020-05-28 17:02 ` [PATCHSET v5 0/12] Add support for async buffered reads Sedat Dilek
2020-05-28 17:02   ` Sedat Dilek
2020-05-28 17:06   ` Jens Axboe
2020-05-28 17:12     ` Sedat Dilek
2020-05-28 17:12       ` Sedat Dilek
2020-05-28 17:14       ` Jens Axboe
2020-05-28 18:20         ` Sedat Dilek
2020-05-28 18:20           ` Sedat Dilek
2020-05-29 10:02     ` Sedat Dilek
2020-05-29 10:02       ` Sedat Dilek
2020-05-29 11:22       ` Sedat Dilek
2020-05-29 11:22         ` Sedat Dilek
2020-05-30 13:36         ` Sedat Dilek
2020-05-30 13:36           ` Sedat Dilek
2020-05-30 18:57           ` Sedat Dilek
2020-05-30 18:57             ` Sedat Dilek
2020-05-31  1:57             ` Jens Axboe
2020-05-31  7:04               ` Sedat Dilek
2020-05-31  7:04                 ` Sedat Dilek
2020-05-31  7:12                 ` Sedat Dilek
2020-05-31  7:12                   ` Sedat Dilek
2020-06-01 13:35                   ` Sedat Dilek
2020-06-01 13:35                     ` Sedat Dilek
2020-06-01 14:04                     ` Jens Axboe [this message]
2020-06-01 14:13                       ` Sedat Dilek
2020-06-01 14:13                         ` Sedat Dilek
2020-06-01 14:14                         ` Jens Axboe
2020-06-01 14:35                           ` Jens Axboe
2020-06-01 14:43                             ` Sedat Dilek
2020-06-01 14:43                               ` Sedat Dilek
2020-06-01 14:46                               ` Jens Axboe
2020-06-01 14:51                                 ` Sedat Dilek
2020-06-01 14:51                                   ` Sedat Dilek
2020-06-01 20:18                                 ` Sedat Dilek
2020-06-01 20:18                                   ` Sedat Dilek
2020-06-04  0:59 ` Andres Freund
2020-06-04  1:04   ` Jens Axboe
2020-06-04  1:30     ` Andres Freund
2020-06-05 19:56       ` Andres Freund
2020-06-05 14:42     ` Jens Axboe
2020-06-05 20:20       ` Andres Freund
2020-06-05 20:21         ` Jens Axboe
2020-06-05 20:36         ` Andres Freund
2020-06-05 20:53           ` Jens Axboe
2020-06-05 21:13             ` Jens Axboe
2020-06-05 21:21               ` Jens Axboe
2020-06-05 22:30                 ` Andres Freund
2020-06-05 22:36                   ` Andres Freund
2020-06-05 22:49                     ` Jens Axboe
2020-06-05 22:54                       ` Andres Freund
2020-06-05 22:56                         ` Jens Axboe
2020-06-05 23:02                           ` Andres Freund
2020-06-06  0:33                 ` Sedat Dilek
2020-06-06  0:33                   ` Sedat Dilek
2020-06-06 16:04                   ` Jens Axboe

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=cdb3ac15-0c41-6147-35f1-41b2a3be1c33@kernel.dk \
    --to=axboe@kernel.dk \
    --cc=akpm@linux-foundation.org \
    --cc=io-uring@vger.kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=sedat.dilek@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.