linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/35 v1] pagevec API cleanups
@ 2017-06-01  9:32 Jan Kara
  2017-06-01  9:32 ` [PATCH 01/35] fscache: Remove unused ->now_uncached callback Jan Kara
                   ` (36 more replies)
  0 siblings, 37 replies; 43+ messages in thread
From: Jan Kara @ 2017-06-01  9:32 UTC (permalink / raw)
  To: linux-mm
  Cc: Hugh Dickins, David Howells, linux-afs, Ryusuke Konishi,
	linux-nilfs, Bob Peterson, cluster-devel, Jaegeuk Kim,
	linux-f2fs-devel, tytso, linux-ext4, Ilya Dryomov, Yan, Zheng,
	ceph-devel, linux-btrfs, David Sterba, Darrick J . Wong,
	linux-xfs, Nadia Yvette Chambers, Jan Kara

Hello,

This series cleans up pagevec API. The original motivation for the series is
the patch "fs: Fix performance regression in clean_bdev_aliases()" however it
has somewhat grown beyond that... The series is pretty large but most of the
patches are trivial in nature. What the series does is:

* Make all pagevec_lookup_ and find_get_ functions update index to where the
  search terminated. Currently tagged page lookup did update the index, other
  variants did not...

* Implement ranged variants for pagevec_lookup and find_get_ functions. Lot
  of callers actually want a ranged lookup and we unnecessarily opencode this
  in lot of them.

* Remove nr_pages argument from pagevec_ API since after implementing ranged
  lookups everyone just wants to pass PAGEVEC_SIZE there.

The conversion of the APIs for entries variants is not such a clear win as
for the other cases as callers tend to play more complex games with indices
etc. (hello THP). I still think the conversion is worth it for consistency
but I'm open to ideas (including just discarding that part) there.

The series also contains several fixes in the beginning to the bugs that I've
found during these cleanups. I've included them to have a clean base (4.12-rc3)
but those should get merged independently (e.g. ext4 fixes are already sitting
in ext4 tree). Also it is possible to split the series in smaller parts (like
convert one API at a time) however I wanted to post the full series so that
people can get the full picture.

The series can be also obtained from my git tree:

git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs.git find_get_pages_range

Opinions and review welcome!

								Honza

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH 01/35] fscache: Remove unused ->now_uncached callback
  2017-06-01  9:32 [PATCH 00/35 v1] pagevec API cleanups Jan Kara
@ 2017-06-01  9:32 ` Jan Kara
  2017-06-01  9:32 ` [PATCH 02/35] ext4: Fix SEEK_HOLE Jan Kara
                   ` (35 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Jan Kara @ 2017-06-01  9:32 UTC (permalink / raw)
  To: linux-mm
  Cc: Hugh Dickins, David Howells, linux-afs, Ryusuke Konishi,
	linux-nilfs, Bob Peterson, cluster-devel, Jaegeuk Kim,
	linux-f2fs-devel, tytso, linux-ext4, Ilya Dryomov, Yan, Zheng,
	ceph-devel, linux-btrfs, David Sterba, Darrick J . Wong,
	linux-xfs, Nadia Yvette Chambers, Jan Kara

The callback doesn't ever get called. Remove it.

Signed-off-by: Jan Kara <jack@suse.cz>
---
 Documentation/filesystems/caching/netfs-api.txt |  2 --
 fs/9p/cache.c                                   | 29 -----------------
 fs/afs/cache.c                                  | 43 -------------------------
 fs/ceph/cache.c                                 | 31 ------------------
 fs/cifs/cache.c                                 | 31 ------------------
 fs/nfs/fscache-index.c                          | 40 -----------------------
 include/linux/fscache.h                         |  9 ------
 7 files changed, 185 deletions(-)

diff --git a/Documentation/filesystems/caching/netfs-api.txt b/Documentation/filesystems/caching/netfs-api.txt
index aed6b94160b1..0eb31de3a2c1 100644
--- a/Documentation/filesystems/caching/netfs-api.txt
+++ b/Documentation/filesystems/caching/netfs-api.txt
@@ -151,8 +151,6 @@ To define an object, a structure of the following type should be filled out:
 		void (*mark_pages_cached)(void *cookie_netfs_data,
 					  struct address_space *mapping,
 					  struct pagevec *cached_pvec);
-
-		void (*now_uncached)(void *cookie_netfs_data);
 	};
 
 This has the following fields:
diff --git a/fs/9p/cache.c b/fs/9p/cache.c
index 103ca5e1267b..64c58eb26159 100644
--- a/fs/9p/cache.c
+++ b/fs/9p/cache.c
@@ -151,34 +151,6 @@ fscache_checkaux v9fs_cache_inode_check_aux(void *cookie_netfs_data,
 	return FSCACHE_CHECKAUX_OKAY;
 }
 
-static void v9fs_cache_inode_now_uncached(void *cookie_netfs_data)
-{
-	struct v9fs_inode *v9inode = cookie_netfs_data;
-	struct pagevec pvec;
-	pgoff_t first;
-	int loop, nr_pages;
-
-	pagevec_init(&pvec, 0);
-	first = 0;
-
-	for (;;) {
-		nr_pages = pagevec_lookup(&pvec, v9inode->vfs_inode.i_mapping,
-					  first,
-					  PAGEVEC_SIZE - pagevec_count(&pvec));
-		if (!nr_pages)
-			break;
-
-		for (loop = 0; loop < nr_pages; loop++)
-			ClearPageFsCache(pvec.pages[loop]);
-
-		first = pvec.pages[nr_pages - 1]->index + 1;
-
-		pvec.nr = nr_pages;
-		pagevec_release(&pvec);
-		cond_resched();
-	}
-}
-
 const struct fscache_cookie_def v9fs_cache_inode_index_def = {
 	.name		= "9p.inode",
 	.type		= FSCACHE_COOKIE_TYPE_DATAFILE,
@@ -186,7 +158,6 @@ const struct fscache_cookie_def v9fs_cache_inode_index_def = {
 	.get_attr	= v9fs_cache_inode_get_attr,
 	.get_aux	= v9fs_cache_inode_get_aux,
 	.check_aux	= v9fs_cache_inode_check_aux,
-	.now_uncached	= v9fs_cache_inode_now_uncached,
 };
 
 void v9fs_cache_inode_get_cookie(struct inode *inode)
diff --git a/fs/afs/cache.c b/fs/afs/cache.c
index 577763c3d88b..1fe855191261 100644
--- a/fs/afs/cache.c
+++ b/fs/afs/cache.c
@@ -39,7 +39,6 @@ static uint16_t afs_vnode_cache_get_aux(const void *cookie_netfs_data,
 static enum fscache_checkaux afs_vnode_cache_check_aux(void *cookie_netfs_data,
 						       const void *buffer,
 						       uint16_t buflen);
-static void afs_vnode_cache_now_uncached(void *cookie_netfs_data);
 
 struct fscache_netfs afs_cache_netfs = {
 	.name			= "afs",
@@ -75,7 +74,6 @@ struct fscache_cookie_def afs_vnode_cache_index_def = {
 	.get_attr		= afs_vnode_cache_get_attr,
 	.get_aux		= afs_vnode_cache_get_aux,
 	.check_aux		= afs_vnode_cache_check_aux,
-	.now_uncached		= afs_vnode_cache_now_uncached,
 };
 
 /*
@@ -359,44 +357,3 @@ static enum fscache_checkaux afs_vnode_cache_check_aux(void *cookie_netfs_data,
 	_leave(" = SUCCESS");
 	return FSCACHE_CHECKAUX_OKAY;
 }
-
-/*
- * indication the cookie is no longer uncached
- * - this function is called when the backing store currently caching a cookie
- *   is removed
- * - the netfs should use this to clean up any markers indicating cached pages
- * - this is mandatory for any object that may have data
- */
-static void afs_vnode_cache_now_uncached(void *cookie_netfs_data)
-{
-	struct afs_vnode *vnode = cookie_netfs_data;
-	struct pagevec pvec;
-	pgoff_t first;
-	int loop, nr_pages;
-
-	_enter("{%x,%x,%Lx}",
-	       vnode->fid.vnode, vnode->fid.unique, vnode->status.data_version);
-
-	pagevec_init(&pvec, 0);
-	first = 0;
-
-	for (;;) {
-		/* grab a bunch of pages to clean */
-		nr_pages = pagevec_lookup(&pvec, vnode->vfs_inode.i_mapping,
-					  first,
-					  PAGEVEC_SIZE - pagevec_count(&pvec));
-		if (!nr_pages)
-			break;
-
-		for (loop = 0; loop < nr_pages; loop++)
-			ClearPageFsCache(pvec.pages[loop]);
-
-		first = pvec.pages[nr_pages - 1]->index + 1;
-
-		pvec.nr = nr_pages;
-		pagevec_release(&pvec);
-		cond_resched();
-	}
-
-	_leave("");
-}
diff --git a/fs/ceph/cache.c b/fs/ceph/cache.c
index 4e7421caf380..edb86ac34051 100644
--- a/fs/ceph/cache.c
+++ b/fs/ceph/cache.c
@@ -137,36 +137,6 @@ static enum fscache_checkaux ceph_fscache_inode_check_aux(
 	return FSCACHE_CHECKAUX_OKAY;
 }
 
-static void ceph_fscache_inode_now_uncached(void* cookie_netfs_data)
-{
-	struct ceph_inode_info* ci = cookie_netfs_data;
-	struct pagevec pvec;
-	pgoff_t first;
-	int loop, nr_pages;
-
-	pagevec_init(&pvec, 0);
-	first = 0;
-
-	dout("ceph inode 0x%p now uncached", ci);
-
-	while (1) {
-		nr_pages = pagevec_lookup(&pvec, ci->vfs_inode.i_mapping, first,
-					  PAGEVEC_SIZE - pagevec_count(&pvec));
-
-		if (!nr_pages)
-			break;
-
-		for (loop = 0; loop < nr_pages; loop++)
-			ClearPageFsCache(pvec.pages[loop]);
-
-		first = pvec.pages[nr_pages - 1]->index + 1;
-
-		pvec.nr = nr_pages;
-		pagevec_release(&pvec);
-		cond_resched();
-	}
-}
-
 static const struct fscache_cookie_def ceph_fscache_inode_object_def = {
 	.name		= "CEPH.inode",
 	.type		= FSCACHE_COOKIE_TYPE_DATAFILE,
@@ -174,7 +144,6 @@ static const struct fscache_cookie_def ceph_fscache_inode_object_def = {
 	.get_attr	= ceph_fscache_inode_get_attr,
 	.get_aux	= ceph_fscache_inode_get_aux,
 	.check_aux	= ceph_fscache_inode_check_aux,
-	.now_uncached	= ceph_fscache_inode_now_uncached,
 };
 
 void ceph_fscache_register_inode_cookie(struct inode *inode)
diff --git a/fs/cifs/cache.c b/fs/cifs/cache.c
index 6c665bf4a27c..2c14020e5e1d 100644
--- a/fs/cifs/cache.c
+++ b/fs/cifs/cache.c
@@ -292,36 +292,6 @@ fscache_checkaux cifs_fscache_inode_check_aux(void *cookie_netfs_data,
 	return FSCACHE_CHECKAUX_OKAY;
 }
 
-static void cifs_fscache_inode_now_uncached(void *cookie_netfs_data)
-{
-	struct cifsInodeInfo *cifsi = cookie_netfs_data;
-	struct pagevec pvec;
-	pgoff_t first;
-	int loop, nr_pages;
-
-	pagevec_init(&pvec, 0);
-	first = 0;
-
-	cifs_dbg(FYI, "%s: cifs inode 0x%p now uncached\n", __func__, cifsi);
-
-	for (;;) {
-		nr_pages = pagevec_lookup(&pvec,
-					  cifsi->vfs_inode.i_mapping, first,
-					  PAGEVEC_SIZE - pagevec_count(&pvec));
-		if (!nr_pages)
-			break;
-
-		for (loop = 0; loop < nr_pages; loop++)
-			ClearPageFsCache(pvec.pages[loop]);
-
-		first = pvec.pages[nr_pages - 1]->index + 1;
-
-		pvec.nr = nr_pages;
-		pagevec_release(&pvec);
-		cond_resched();
-	}
-}
-
 const struct fscache_cookie_def cifs_fscache_inode_object_def = {
 	.name		= "CIFS.uniqueid",
 	.type		= FSCACHE_COOKIE_TYPE_DATAFILE,
@@ -329,5 +299,4 @@ const struct fscache_cookie_def cifs_fscache_inode_object_def = {
 	.get_attr	= cifs_fscache_inode_get_attr,
 	.get_aux	= cifs_fscache_inode_get_aux,
 	.check_aux	= cifs_fscache_inode_check_aux,
-	.now_uncached	= cifs_fscache_inode_now_uncached,
 };
diff --git a/fs/nfs/fscache-index.c b/fs/nfs/fscache-index.c
index 777b055063f6..3025fe8584a0 100644
--- a/fs/nfs/fscache-index.c
+++ b/fs/nfs/fscache-index.c
@@ -252,45 +252,6 @@ enum fscache_checkaux nfs_fscache_inode_check_aux(void *cookie_netfs_data,
 }
 
 /*
- * Indication from FS-Cache that the cookie is no longer cached
- * - This function is called when the backing store currently caching a cookie
- *   is removed
- * - The netfs should use this to clean up any markers indicating cached pages
- * - This is mandatory for any object that may have data
- */
-static void nfs_fscache_inode_now_uncached(void *cookie_netfs_data)
-{
-	struct nfs_inode *nfsi = cookie_netfs_data;
-	struct pagevec pvec;
-	pgoff_t first;
-	int loop, nr_pages;
-
-	pagevec_init(&pvec, 0);
-	first = 0;
-
-	dprintk("NFS: nfs_inode_now_uncached: nfs_inode 0x%p\n", nfsi);
-
-	for (;;) {
-		/* grab a bunch of pages to unmark */
-		nr_pages = pagevec_lookup(&pvec,
-					  nfsi->vfs_inode.i_mapping,
-					  first,
-					  PAGEVEC_SIZE - pagevec_count(&pvec));
-		if (!nr_pages)
-			break;
-
-		for (loop = 0; loop < nr_pages; loop++)
-			ClearPageFsCache(pvec.pages[loop]);
-
-		first = pvec.pages[nr_pages - 1]->index + 1;
-
-		pvec.nr = nr_pages;
-		pagevec_release(&pvec);
-		cond_resched();
-	}
-}
-
-/*
  * Get an extra reference on a read context.
  * - This function can be absent if the completion function doesn't require a
  *   context.
@@ -330,7 +291,6 @@ const struct fscache_cookie_def nfs_fscache_inode_object_def = {
 	.get_attr	= nfs_fscache_inode_get_attr,
 	.get_aux	= nfs_fscache_inode_get_aux,
 	.check_aux	= nfs_fscache_inode_check_aux,
-	.now_uncached	= nfs_fscache_inode_now_uncached,
 	.get_context	= nfs_fh_get_context,
 	.put_context	= nfs_fh_put_context,
 };
diff --git a/include/linux/fscache.h b/include/linux/fscache.h
index 115bb81912cc..f4ff47d4a893 100644
--- a/include/linux/fscache.h
+++ b/include/linux/fscache.h
@@ -143,15 +143,6 @@ struct fscache_cookie_def {
 	void (*mark_page_cached)(void *cookie_netfs_data,
 				 struct address_space *mapping,
 				 struct page *page);
-
-	/* indicate the cookie is no longer cached
-	 * - this function is called when the backing store currently caching
-	 *   a cookie is removed
-	 * - the netfs should use this to clean up any markers indicating
-	 *   cached pages
-	 * - this is mandatory for any object that may have data
-	 */
-	void (*now_uncached)(void *cookie_netfs_data);
 };
 
 /*
-- 
2.12.3

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 02/35] ext4: Fix SEEK_HOLE
  2017-06-01  9:32 [PATCH 00/35 v1] pagevec API cleanups Jan Kara
  2017-06-01  9:32 ` [PATCH 01/35] fscache: Remove unused ->now_uncached callback Jan Kara
@ 2017-06-01  9:32 ` Jan Kara
  2017-06-01  9:32 ` [PATCH 03/35] ext4: Fix off-by-in in loop termination in ext4_find_unwritten_pgoff() Jan Kara
                   ` (34 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Jan Kara @ 2017-06-01  9:32 UTC (permalink / raw)
  To: linux-mm
  Cc: Hugh Dickins, David Howells, linux-afs, Ryusuke Konishi,
	linux-nilfs, Bob Peterson, cluster-devel, Jaegeuk Kim,
	linux-f2fs-devel, tytso, linux-ext4, Ilya Dryomov, Yan, Zheng,
	ceph-devel, linux-btrfs, David Sterba, Darrick J . Wong,
	linux-xfs, Nadia Yvette Chambers, Jan Kara, stable, Zheng Liu

Currently, SEEK_HOLE implementation in ext4 may both return that there's
a hole at some offset although that offset already has data and skip
some holes during a search for the next hole. The first problem is
demostrated by:

xfs_io -c "falloc 0 256k" -c "pwrite 0 56k" -c "seek -h 0" file
wrote 57344/57344 bytes at offset 0
56 KiB, 14 ops; 0.0000 sec (2.054 GiB/sec and 538461.5385 ops/sec)
Whence	Result
HOLE	0

Where we can see that SEEK_HOLE wrongly returned offset 0 as containing
a hole although we have written data there. The second problem can be
demonstrated by:

xfs_io -c "falloc 0 256k" -c "pwrite 0 56k" -c "pwrite 128k 8k"
       -c "seek -h 0" file

wrote 57344/57344 bytes at offset 0
56 KiB, 14 ops; 0.0000 sec (1.978 GiB/sec and 518518.5185 ops/sec)
wrote 8192/8192 bytes at offset 131072
8 KiB, 2 ops; 0.0000 sec (2 GiB/sec and 500000.0000 ops/sec)
Whence	Result
HOLE	139264

Where we can see that hole at offsets 56k..128k has been ignored by the
SEEK_HOLE call.

The underlying problem is in the ext4_find_unwritten_pgoff() which is
just buggy. In some cases it fails to update returned offset when it
finds a hole (when no pages are found or when the first found page has
higher index than expected), in some cases conditions for detecting hole
are just missing (we fail to detect a situation where indices of
returned pages are not contiguous).

Fix ext4_find_unwritten_pgoff() to properly detect non-contiguous page
indices and also handle all cases where we got less pages then expected
in one place and handle it properly there.

CC: stable@vger.kernel.org
Fixes: c8c0df241cc2719b1262e627f999638411934f60
CC: Zheng Liu <wenqing.lz@taobao.com>
Signed-off-by: Jan Kara <jack@suse.cz>
---
 fs/ext4/file.c | 50 ++++++++++++++------------------------------------
 1 file changed, 14 insertions(+), 36 deletions(-)

diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index 831fd6beebf0..bbea2dccd584 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -484,47 +484,27 @@ static int ext4_find_unwritten_pgoff(struct inode *inode,
 		num = min_t(pgoff_t, end - index, PAGEVEC_SIZE);
 		nr_pages = pagevec_lookup(&pvec, inode->i_mapping, index,
 					  (pgoff_t)num);
-		if (nr_pages == 0) {
-			if (whence == SEEK_DATA)
-				break;
-
-			BUG_ON(whence != SEEK_HOLE);
-			/*
-			 * If this is the first time to go into the loop and
-			 * offset is not beyond the end offset, it will be a
-			 * hole at this offset
-			 */
-			if (lastoff == startoff || lastoff < endoff)
-				found = 1;
-			break;
-		}
-
-		/*
-		 * If this is the first time to go into the loop and
-		 * offset is smaller than the first page offset, it will be a
-		 * hole at this offset.
-		 */
-		if (lastoff == startoff && whence == SEEK_HOLE &&
-		    lastoff < page_offset(pvec.pages[0])) {
-			found = 1;
+		if (nr_pages == 0)
 			break;
-		}
 
 		for (i = 0; i < nr_pages; i++) {
 			struct page *page = pvec.pages[i];
 			struct buffer_head *bh, *head;
 
 			/*
-			 * If the current offset is not beyond the end of given
-			 * range, it will be a hole.
+			 * If current offset is smaller than the page offset,
+			 * there is a hole at this offset.
 			 */
-			if (lastoff < endoff && whence == SEEK_HOLE &&
-			    page->index > end) {
+			if (whence == SEEK_HOLE && lastoff < endoff &&
+			    lastoff < page_offset(pvec.pages[i])) {
 				found = 1;
 				*offset = lastoff;
 				goto out;
 			}
 
+			if (page->index > end)
+				goto out;
+
 			lock_page(page);
 
 			if (unlikely(page->mapping != inode->i_mapping)) {
@@ -564,20 +544,18 @@ static int ext4_find_unwritten_pgoff(struct inode *inode,
 			unlock_page(page);
 		}
 
-		/*
-		 * The no. of pages is less than our desired, that would be a
-		 * hole in there.
-		 */
-		if (nr_pages < num && whence == SEEK_HOLE) {
-			found = 1;
-			*offset = lastoff;
+		/* The no. of pages is less than our desired, we are done. */
+		if (nr_pages < num)
 			break;
-		}
 
 		index = pvec.pages[i - 1]->index + 1;
 		pagevec_release(&pvec);
 	} while (index <= end);
 
+	if (whence == SEEK_HOLE && lastoff < endoff) {
+		found = 1;
+		*offset = lastoff;
+	}
 out:
 	pagevec_release(&pvec);
 	return found;
-- 
2.12.3

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 03/35] ext4: Fix off-by-in in loop termination in ext4_find_unwritten_pgoff()
  2017-06-01  9:32 [PATCH 00/35 v1] pagevec API cleanups Jan Kara
  2017-06-01  9:32 ` [PATCH 01/35] fscache: Remove unused ->now_uncached callback Jan Kara
  2017-06-01  9:32 ` [PATCH 02/35] ext4: Fix SEEK_HOLE Jan Kara
@ 2017-06-01  9:32 ` Jan Kara
  2017-06-01  9:32 ` [PATCH 04/35] dax: Fix inefficiency in dax_writeback_mapping_range() Jan Kara
                   ` (33 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Jan Kara @ 2017-06-01  9:32 UTC (permalink / raw)
  To: linux-mm
  Cc: Hugh Dickins, David Howells, linux-afs, Ryusuke Konishi,
	linux-nilfs, Bob Peterson, cluster-devel, Jaegeuk Kim,
	linux-f2fs-devel, tytso, linux-ext4, Ilya Dryomov, Yan, Zheng,
	ceph-devel, linux-btrfs, David Sterba, Darrick J . Wong,
	linux-xfs, Nadia Yvette Chambers, Jan Kara

There is an off-by-one error in loop termination conditions in
ext4_find_unwritten_pgoff() since 'end' may index a page beyond end of
desired range if 'endoff' is page aligned. It doesn't have any visible
effects but still it is good to fix it.

Signed-off-by: Jan Kara <jack@suse.cz>
---
 fs/ext4/file.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index bbea2dccd584..2b00bf84c05b 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -474,7 +474,7 @@ static int ext4_find_unwritten_pgoff(struct inode *inode,
 	endoff = (loff_t)end_blk << blkbits;
 
 	index = startoff >> PAGE_SHIFT;
-	end = endoff >> PAGE_SHIFT;
+	end = (endoff - 1) >> PAGE_SHIFT;
 
 	pagevec_init(&pvec, 0);
 	do {
-- 
2.12.3

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 04/35] dax: Fix inefficiency in dax_writeback_mapping_range()
  2017-06-01  9:32 [PATCH 00/35 v1] pagevec API cleanups Jan Kara
                   ` (2 preceding siblings ...)
  2017-06-01  9:32 ` [PATCH 03/35] ext4: Fix off-by-in in loop termination in ext4_find_unwritten_pgoff() Jan Kara
@ 2017-06-01  9:32 ` Jan Kara
  2017-06-01  9:32 ` [PATCH 05/35] mm: Fix THP handling in invalidate_mapping_pages() Jan Kara
                   ` (32 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Jan Kara @ 2017-06-01  9:32 UTC (permalink / raw)
  To: linux-mm
  Cc: Hugh Dickins, David Howells, linux-afs, Ryusuke Konishi,
	linux-nilfs, Bob Peterson, cluster-devel, Jaegeuk Kim,
	linux-f2fs-devel, tytso, linux-ext4, Ilya Dryomov, Yan, Zheng,
	ceph-devel, linux-btrfs, David Sterba, Darrick J . Wong,
	linux-xfs, Nadia Yvette Chambers, Jan Kara, stable

dax_writeback_mapping_range() fails to update iteration index when
searching radix tree for entries needing cache flushing. Thus each
pagevec worth of entries is searched starting from the start which is
inefficient and prone to livelocks. Update index properly.

CC: stable@vger.kernel.org
Fixes: 9973c98ecfda3a1dfcab981665b5f1e39bcde64a
Signed-off-by: Jan Kara <jack@suse.cz>
---
 fs/dax.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/fs/dax.c b/fs/dax.c
index c22eaf162f95..c204445a69b0 100644
--- a/fs/dax.c
+++ b/fs/dax.c
@@ -859,6 +859,7 @@ int dax_writeback_mapping_range(struct address_space *mapping,
 			if (ret < 0)
 				goto out;
 		}
+		start_index = indices[pvec.nr - 1] + 1;
 	}
 out:
 	put_dax(dax_dev);
-- 
2.12.3

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 05/35] mm: Fix THP handling in invalidate_mapping_pages()
  2017-06-01  9:32 [PATCH 00/35 v1] pagevec API cleanups Jan Kara
                   ` (3 preceding siblings ...)
  2017-06-01  9:32 ` [PATCH 04/35] dax: Fix inefficiency in dax_writeback_mapping_range() Jan Kara
@ 2017-06-01  9:32 ` Jan Kara
  2017-06-01  9:32 ` [PATCH 06/35] mm: Make pagevec_lookup() update index Jan Kara
                   ` (31 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Jan Kara @ 2017-06-01  9:32 UTC (permalink / raw)
  To: linux-mm
  Cc: Hugh Dickins, David Howells, linux-afs, Ryusuke Konishi,
	linux-nilfs, Bob Peterson, cluster-devel, Jaegeuk Kim,
	linux-f2fs-devel, tytso, linux-ext4, Ilya Dryomov, Yan, Zheng,
	ceph-devel, linux-btrfs, David Sterba, Darrick J . Wong,
	linux-xfs, Nadia Yvette Chambers, Jan Kara

The condition checking for THP straddling end of invalidated range is
wrong - it checks 'index' against 'end' but 'index' has been already
advanced to point to the end of THP and thus the condition can never be
true. As a result THP straddling 'end' has been fully invalidated. Given
the nature of invalidate_mapping_pages(), this could be only performance
issue. In fact, we are lucky the condition is wrong because if it was
ever true, we'd leave locked page behind.

Fix the condition checking for THP straddling 'end' and also properly
unlock the page. Also update the comment before the condition to explain
why we decide not to invalidate the page as it was not clear to me and I
had to ask Kirill.

Signed-off-by: Jan Kara <jack@suse.cz>
---
 mm/truncate.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/mm/truncate.c b/mm/truncate.c
index 6479ed2afc53..2330223841fb 100644
--- a/mm/truncate.c
+++ b/mm/truncate.c
@@ -530,9 +530,15 @@ unsigned long invalidate_mapping_pages(struct address_space *mapping,
 			} else if (PageTransHuge(page)) {
 				index += HPAGE_PMD_NR - 1;
 				i += HPAGE_PMD_NR - 1;
-				/* 'end' is in the middle of THP */
-				if (index ==  round_down(end, HPAGE_PMD_NR))
+				/*
+				 * 'end' is in the middle of THP. Don't
+				 * invalidate the page as the part outside of
+				 * 'end' could be still useful.
+				 */
+				if (index > end) {
+					unlock_page(page);
 					continue;
+				}
 			}
 
 			ret = invalidate_inode_page(page);
-- 
2.12.3

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 06/35] mm: Make pagevec_lookup() update index
  2017-06-01  9:32 [PATCH 00/35 v1] pagevec API cleanups Jan Kara
                   ` (4 preceding siblings ...)
  2017-06-01  9:32 ` [PATCH 05/35] mm: Fix THP handling in invalidate_mapping_pages() Jan Kara
@ 2017-06-01  9:32 ` Jan Kara
  2017-06-01  9:32 ` [PATCH 07/35] mm: Implement find_get_pages_range() Jan Kara
                   ` (30 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Jan Kara @ 2017-06-01  9:32 UTC (permalink / raw)
  To: linux-mm
  Cc: Hugh Dickins, David Howells, linux-afs, Ryusuke Konishi,
	linux-nilfs, Bob Peterson, cluster-devel, Jaegeuk Kim,
	linux-f2fs-devel, tytso, linux-ext4, Ilya Dryomov, Yan, Zheng,
	ceph-devel, linux-btrfs, David Sterba, Darrick J . Wong,
	linux-xfs, Nadia Yvette Chambers, Jan Kara

Make pagevec_lookup() (and underlying find_get_pages()) update index to
the next page where iteration should continue. Most callers want this
and also pagevec_lookup_tag() already does this.

Signed-off-by: Jan Kara <jack@suse.cz>
---
 fs/buffer.c             |  6 ++----
 fs/ext4/file.c          |  4 +---
 fs/ext4/inode.c         |  8 ++------
 fs/fscache/page.c       |  5 ++---
 fs/hugetlbfs/inode.c    | 17 ++++++++---------
 fs/nilfs2/page.c        |  3 +--
 fs/ramfs/file-nommu.c   |  2 +-
 fs/xfs/xfs_file.c       |  3 +--
 include/linux/pagemap.h |  2 +-
 include/linux/pagevec.h |  2 +-
 mm/filemap.c            |  9 +++++++--
 mm/swap.c               |  5 +++--
 12 files changed, 30 insertions(+), 36 deletions(-)

diff --git a/fs/buffer.c b/fs/buffer.c
index 161be58c5cb0..fe0ee01c5a44 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -1638,13 +1638,12 @@ void clean_bdev_aliases(struct block_device *bdev, sector_t block, sector_t len)
 
 	end = (block + len - 1) >> (PAGE_SHIFT - bd_inode->i_blkbits);
 	pagevec_init(&pvec, 0);
-	while (index <= end && pagevec_lookup(&pvec, bd_mapping, index,
+	while (index <= end && pagevec_lookup(&pvec, bd_mapping, &index,
 			min(end - index, (pgoff_t)PAGEVEC_SIZE - 1) + 1)) {
 		for (i = 0; i < pagevec_count(&pvec); i++) {
 			struct page *page = pvec.pages[i];
 
-			index = page->index;
-			if (index > end)
+			if (page->index > end)
 				break;
 			if (!page_has_buffers(page))
 				continue;
@@ -1675,7 +1674,6 @@ void clean_bdev_aliases(struct block_device *bdev, sector_t block, sector_t len)
 		}
 		pagevec_release(&pvec);
 		cond_resched();
-		index++;
 	}
 }
 EXPORT_SYMBOL(clean_bdev_aliases);
diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index 2b00bf84c05b..ddca17c7875a 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -482,7 +482,7 @@ static int ext4_find_unwritten_pgoff(struct inode *inode,
 		unsigned long nr_pages;
 
 		num = min_t(pgoff_t, end - index, PAGEVEC_SIZE);
-		nr_pages = pagevec_lookup(&pvec, inode->i_mapping, index,
+		nr_pages = pagevec_lookup(&pvec, inode->i_mapping, &index,
 					  (pgoff_t)num);
 		if (nr_pages == 0)
 			break;
@@ -547,8 +547,6 @@ static int ext4_find_unwritten_pgoff(struct inode *inode,
 		/* The no. of pages is less than our desired, we are done. */
 		if (nr_pages < num)
 			break;
-
-		index = pvec.pages[i - 1]->index + 1;
 		pagevec_release(&pvec);
 	} while (index <= end);
 
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 1bd0bfa547f6..784f41328dc8 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -1670,7 +1670,7 @@ static void mpage_release_unused_pages(struct mpage_da_data *mpd,
 
 	pagevec_init(&pvec, 0);
 	while (index <= end) {
-		nr_pages = pagevec_lookup(&pvec, mapping, index, PAGEVEC_SIZE);
+		nr_pages = pagevec_lookup(&pvec, mapping, &index, PAGEVEC_SIZE);
 		if (nr_pages == 0)
 			break;
 		for (i = 0; i < nr_pages; i++) {
@@ -1687,7 +1687,6 @@ static void mpage_release_unused_pages(struct mpage_da_data *mpd,
 			}
 			unlock_page(page);
 		}
-		index = pvec.pages[nr_pages - 1]->index + 1;
 		pagevec_release(&pvec);
 	}
 }
@@ -2284,7 +2283,7 @@ static int mpage_map_and_submit_buffers(struct mpage_da_data *mpd)
 
 	pagevec_init(&pvec, 0);
 	while (start <= end) {
-		nr_pages = pagevec_lookup(&pvec, inode->i_mapping, start,
+		nr_pages = pagevec_lookup(&pvec, inode->i_mapping, &start,
 					  PAGEVEC_SIZE);
 		if (nr_pages == 0)
 			break;
@@ -2293,8 +2292,6 @@ static int mpage_map_and_submit_buffers(struct mpage_da_data *mpd)
 
 			if (page->index > end)
 				break;
-			/* Up to 'end' pages must be contiguous */
-			BUG_ON(page->index != start);
 			bh = head = page_buffers(page);
 			do {
 				if (lblk < mpd->map.m_lblk)
@@ -2339,7 +2336,6 @@ static int mpage_map_and_submit_buffers(struct mpage_da_data *mpd)
 				pagevec_release(&pvec);
 				return err;
 			}
-			start++;
 		}
 		pagevec_release(&pvec);
 	}
diff --git a/fs/fscache/page.c b/fs/fscache/page.c
index c8c4f79c7ce1..83018861dcd2 100644
--- a/fs/fscache/page.c
+++ b/fs/fscache/page.c
@@ -1178,11 +1178,10 @@ void __fscache_uncache_all_inode_pages(struct fscache_cookie *cookie,
 	pagevec_init(&pvec, 0);
 	next = 0;
 	do {
-		if (!pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE))
+		if (!pagevec_lookup(&pvec, mapping, &next, PAGEVEC_SIZE))
 			break;
 		for (i = 0; i < pagevec_count(&pvec); i++) {
 			struct page *page = pvec.pages[i];
-			next = page->index;
 			if (PageFsCache(page)) {
 				__fscache_wait_on_page_write(cookie, page);
 				__fscache_uncache_page(cookie, page);
@@ -1190,7 +1189,7 @@ void __fscache_uncache_all_inode_pages(struct fscache_cookie *cookie,
 		}
 		pagevec_release(&pvec);
 		cond_resched();
-	} while (++next);
+	} while (next);
 
 	_leave("");
 }
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index dde861387a40..372fc8aac38e 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -401,7 +401,7 @@ static void remove_inode_hugepages(struct inode *inode, loff_t lstart,
 	const pgoff_t end = lend >> huge_page_shift(h);
 	struct vm_area_struct pseudo_vma;
 	struct pagevec pvec;
-	pgoff_t next;
+	pgoff_t next, index;
 	int i, freed = 0;
 	long lookup_nr = PAGEVEC_SIZE;
 	bool truncate_op = (lend == LLONG_MAX);
@@ -420,7 +420,7 @@ static void remove_inode_hugepages(struct inode *inode, loff_t lstart,
 		/*
 		 * When no more pages are found, we are done.
 		 */
-		if (!pagevec_lookup(&pvec, mapping, next, lookup_nr))
+		if (!pagevec_lookup(&pvec, mapping, &next, lookup_nr))
 			break;
 
 		for (i = 0; i < pagevec_count(&pvec); ++i) {
@@ -432,13 +432,13 @@ static void remove_inode_hugepages(struct inode *inode, loff_t lstart,
 			 * only possible in the punch hole case as end is
 			 * max page offset in the truncate case.
 			 */
-			next = page->index;
-			if (next >= end)
+			index = page->index;
+			if (index >= end)
 				break;
 
 			hash = hugetlb_fault_mutex_hash(h, current->mm,
 							&pseudo_vma,
-							mapping, next, 0);
+							mapping, index, 0);
 			mutex_lock(&hugetlb_fault_mutex_table[hash]);
 
 			/*
@@ -455,8 +455,8 @@ static void remove_inode_hugepages(struct inode *inode, loff_t lstart,
 
 				i_mmap_lock_write(mapping);
 				hugetlb_vmdelete_list(&mapping->i_mmap,
-					next * pages_per_huge_page(h),
-					(next + 1) * pages_per_huge_page(h));
+					index * pages_per_huge_page(h),
+					(index + 1) * pages_per_huge_page(h));
 				i_mmap_unlock_write(mapping);
 			}
 
@@ -475,14 +475,13 @@ static void remove_inode_hugepages(struct inode *inode, loff_t lstart,
 			freed++;
 			if (!truncate_op) {
 				if (unlikely(hugetlb_unreserve_pages(inode,
-							next, next + 1, 1)))
+							index, index + 1, 1)))
 					hugetlb_fix_reserve_counts(inode);
 			}
 
 			unlock_page(page);
 			mutex_unlock(&hugetlb_fault_mutex_table[hash]);
 		}
-		++next;
 		huge_pagevec_release(&pvec);
 		cond_resched();
 	}
diff --git a/fs/nilfs2/page.c b/fs/nilfs2/page.c
index f11a3ad2df0c..382a36c72d72 100644
--- a/fs/nilfs2/page.c
+++ b/fs/nilfs2/page.c
@@ -312,10 +312,9 @@ void nilfs_copy_back_pages(struct address_space *dmap,
 
 	pagevec_init(&pvec, 0);
 repeat:
-	n = pagevec_lookup(&pvec, smap, index, PAGEVEC_SIZE);
+	n = pagevec_lookup(&pvec, smap, &index, PAGEVEC_SIZE);
 	if (!n)
 		return;
-	index = pvec.pages[n - 1]->index + 1;
 
 	for (i = 0; i < pagevec_count(&pvec); i++) {
 		struct page *page = pvec.pages[i], *dpage;
diff --git a/fs/ramfs/file-nommu.c b/fs/ramfs/file-nommu.c
index 2ef7ce75c062..3ac1f2387083 100644
--- a/fs/ramfs/file-nommu.c
+++ b/fs/ramfs/file-nommu.c
@@ -228,7 +228,7 @@ static unsigned long ramfs_nommu_get_unmapped_area(struct file *file,
 	if (!pages)
 		goto out_free;
 
-	nr = find_get_pages(inode->i_mapping, pgoff, lpages, pages);
+	nr = find_get_pages(inode->i_mapping, &pgoff, lpages, pages);
 	if (nr != lpages)
 		goto out_free_pages; /* leave if some pages were missing */
 
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index 5fb5a0958a14..487342078fc7 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -1050,7 +1050,7 @@ xfs_find_get_desired_pgoff(
 		unsigned int	i;
 
 		want = min_t(pgoff_t, end - index, PAGEVEC_SIZE - 1) + 1;
-		nr_pages = pagevec_lookup(&pvec, inode->i_mapping, index,
+		nr_pages = pagevec_lookup(&pvec, inode->i_mapping, &index,
 					  want);
 		if (nr_pages == 0)
 			break;
@@ -1124,7 +1124,6 @@ xfs_find_get_desired_pgoff(
 		if (nr_pages < want)
 			break;
 
-		index = pvec.pages[i - 1]->index + 1;
 		pagevec_release(&pvec);
 	} while (index <= end);
 
diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
index 316a19f6b635..86de6f9c8607 100644
--- a/include/linux/pagemap.h
+++ b/include/linux/pagemap.h
@@ -336,7 +336,7 @@ struct page *find_lock_entry(struct address_space *mapping, pgoff_t offset);
 unsigned find_get_entries(struct address_space *mapping, pgoff_t start,
 			  unsigned int nr_entries, struct page **entries,
 			  pgoff_t *indices);
-unsigned find_get_pages(struct address_space *mapping, pgoff_t start,
+unsigned find_get_pages(struct address_space *mapping, pgoff_t *start,
 			unsigned int nr_pages, struct page **pages);
 unsigned find_get_pages_contig(struct address_space *mapping, pgoff_t start,
 			       unsigned int nr_pages, struct page **pages);
diff --git a/include/linux/pagevec.h b/include/linux/pagevec.h
index b45d391b4540..c395a5bb58b2 100644
--- a/include/linux/pagevec.h
+++ b/include/linux/pagevec.h
@@ -28,7 +28,7 @@ unsigned pagevec_lookup_entries(struct pagevec *pvec,
 				pgoff_t *indices);
 void pagevec_remove_exceptionals(struct pagevec *pvec);
 unsigned pagevec_lookup(struct pagevec *pvec, struct address_space *mapping,
-		pgoff_t start, unsigned nr_pages);
+		pgoff_t *start, unsigned nr_pages);
 unsigned pagevec_lookup_tag(struct pagevec *pvec,
 		struct address_space *mapping, pgoff_t *index, int tag,
 		unsigned nr_pages);
diff --git a/mm/filemap.c b/mm/filemap.c
index 6f1be573a5e6..10d926a423e2 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -1450,10 +1450,11 @@ unsigned find_get_entries(struct address_space *mapping,
  *
  * The search returns a group of mapping-contiguous pages with ascending
  * indexes.  There may be holes in the indices due to not-present pages.
+ * We also update @start to index the next page for the traversal.
  *
  * find_get_pages() returns the number of pages which were found.
  */
-unsigned find_get_pages(struct address_space *mapping, pgoff_t start,
+unsigned find_get_pages(struct address_space *mapping, pgoff_t *start,
 			    unsigned int nr_pages, struct page **pages)
 {
 	struct radix_tree_iter iter;
@@ -1464,7 +1465,7 @@ unsigned find_get_pages(struct address_space *mapping, pgoff_t start,
 		return 0;
 
 	rcu_read_lock();
-	radix_tree_for_each_slot(slot, &mapping->page_tree, &iter, start) {
+	radix_tree_for_each_slot(slot, &mapping->page_tree, &iter, *start) {
 		struct page *head, *page;
 repeat:
 		page = radix_tree_deref_slot(slot);
@@ -1506,6 +1507,10 @@ unsigned find_get_pages(struct address_space *mapping, pgoff_t start,
 	}
 
 	rcu_read_unlock();
+
+	if (ret)
+		*start = pages[ret - 1]->index + 1;
+
 	return ret;
 }
 
diff --git a/mm/swap.c b/mm/swap.c
index 98d08b4579fa..368d627cf279 100644
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -951,12 +951,13 @@ void pagevec_remove_exceptionals(struct pagevec *pvec)
  * reference against the pages in @pvec.
  *
  * The search returns a group of mapping-contiguous pages with ascending
- * indexes.  There may be holes in the indices due to not-present pages.
+ * indexes.  There may be holes in the indices due to not-present pages. We
+ * also update @start to index the next page for the traversal.
  *
  * pagevec_lookup() returns the number of pages which were found.
  */
 unsigned pagevec_lookup(struct pagevec *pvec, struct address_space *mapping,
-		pgoff_t start, unsigned nr_pages)
+		pgoff_t *start, unsigned nr_pages)
 {
 	pvec->nr = find_get_pages(mapping, start, nr_pages, pvec->pages);
 	return pagevec_count(pvec);
-- 
2.12.3

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 07/35] mm: Implement find_get_pages_range()
  2017-06-01  9:32 [PATCH 00/35 v1] pagevec API cleanups Jan Kara
                   ` (5 preceding siblings ...)
  2017-06-01  9:32 ` [PATCH 06/35] mm: Make pagevec_lookup() update index Jan Kara
@ 2017-06-01  9:32 ` Jan Kara
  2017-06-01  9:32 ` [PATCH 08/35] fs: Fix performance regression in clean_bdev_aliases() Jan Kara
                   ` (29 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Jan Kara @ 2017-06-01  9:32 UTC (permalink / raw)
  To: linux-mm
  Cc: Hugh Dickins, David Howells, linux-afs, Ryusuke Konishi,
	linux-nilfs, Bob Peterson, cluster-devel, Jaegeuk Kim,
	linux-f2fs-devel, tytso, linux-ext4, Ilya Dryomov, Yan, Zheng,
	ceph-devel, linux-btrfs, David Sterba, Darrick J . Wong,
	linux-xfs, Nadia Yvette Chambers, Jan Kara

Implement a variant of find_get_pages() that stops iterating at given
index. This may be substantial performance gain if the mapping is
sparse. See following commit for details. Furthermore lots of users of
this function (through pagevec_lookup()) actually want a range lookup
and all of them are currently open-coding this.

Also create corresponding pagevec_lookup_range() function.

Signed-off-by: Jan Kara <jack@suse.cz>
---
 include/linux/pagemap.h | 12 ++++++++++--
 include/linux/pagevec.h | 13 +++++++++++--
 mm/filemap.c            | 42 ++++++++++++++++++++++++++++++------------
 mm/swap.c               | 22 ++++++++++++++--------
 4 files changed, 65 insertions(+), 24 deletions(-)

diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
index 86de6f9c8607..2bb5e636a8c8 100644
--- a/include/linux/pagemap.h
+++ b/include/linux/pagemap.h
@@ -336,8 +336,16 @@ struct page *find_lock_entry(struct address_space *mapping, pgoff_t offset);
 unsigned find_get_entries(struct address_space *mapping, pgoff_t start,
 			  unsigned int nr_entries, struct page **entries,
 			  pgoff_t *indices);
-unsigned find_get_pages(struct address_space *mapping, pgoff_t *start,
-			unsigned int nr_pages, struct page **pages);
+unsigned find_get_pages_range(struct address_space *mapping, pgoff_t *start,
+			pgoff_t end, unsigned int nr_pages,
+			struct page **pages);
+static inline unsigned find_get_pages(struct address_space *mapping,
+			pgoff_t *start, unsigned int nr_pages,
+			struct page **pages)
+{
+	return find_get_pages_range(mapping, start, (pgoff_t)-1, nr_pages,
+				    pages);
+}
 unsigned find_get_pages_contig(struct address_space *mapping, pgoff_t start,
 			       unsigned int nr_pages, struct page **pages);
 unsigned find_get_pages_tag(struct address_space *mapping, pgoff_t *index,
diff --git a/include/linux/pagevec.h b/include/linux/pagevec.h
index c395a5bb58b2..7df056910437 100644
--- a/include/linux/pagevec.h
+++ b/include/linux/pagevec.h
@@ -27,8 +27,17 @@ unsigned pagevec_lookup_entries(struct pagevec *pvec,
 				pgoff_t start, unsigned nr_entries,
 				pgoff_t *indices);
 void pagevec_remove_exceptionals(struct pagevec *pvec);
-unsigned pagevec_lookup(struct pagevec *pvec, struct address_space *mapping,
-		pgoff_t *start, unsigned nr_pages);
+unsigned pagevec_lookup_range(struct pagevec *pvec,
+			      struct address_space *mapping,
+			      pgoff_t *start, pgoff_t end, unsigned nr_pages);
+static inline unsigned pagevec_lookup(struct pagevec *pvec,
+				      struct address_space *mapping,
+				      pgoff_t *start, unsigned nr_pages)
+{
+	return pagevec_lookup_range(pvec, mapping, start, (pgoff_t)-1,
+				    nr_pages);
+}
+
 unsigned pagevec_lookup_tag(struct pagevec *pvec,
 		struct address_space *mapping, pgoff_t *index, int tag,
 		unsigned nr_pages);
diff --git a/mm/filemap.c b/mm/filemap.c
index 10d926a423e2..2693f87a7968 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -1438,24 +1438,29 @@ unsigned find_get_entries(struct address_space *mapping,
 }
 
 /**
- * find_get_pages - gang pagecache lookup
+ * find_get_pages_range - gang pagecache lookup
  * @mapping:	The address_space to search
  * @start:	The starting page index
+ * @end:	The final page index (inclusive)
  * @nr_pages:	The maximum number of pages
  * @pages:	Where the resulting pages are placed
  *
- * find_get_pages() will search for and return a group of up to
- * @nr_pages pages in the mapping.  The pages are placed at @pages.
- * find_get_pages() takes a reference against the returned pages.
+ * find_get_pages_range() will search for and return a group of up to @nr_pages
+ * pages in the mapping starting at index @start and up to index @end
+ * (inclusive).  The pages are placed at @pages.  find_get_pages_range() takes
+ * a reference against the returned pages.
  *
  * The search returns a group of mapping-contiguous pages with ascending
  * indexes.  There may be holes in the indices due to not-present pages.
  * We also update @start to index the next page for the traversal.
  *
- * find_get_pages() returns the number of pages which were found.
+ * find_get_pages_range() returns the number of pages which were found. If this
+ * number is smaller than @nr_pages, the end of specified range has been
+ * reached.
  */
-unsigned find_get_pages(struct address_space *mapping, pgoff_t *start,
-			    unsigned int nr_pages, struct page **pages)
+unsigned find_get_pages_range(struct address_space *mapping, pgoff_t *start,
+			      pgoff_t end, unsigned int nr_pages,
+			      struct page **pages)
 {
 	struct radix_tree_iter iter;
 	void **slot;
@@ -1467,6 +1472,9 @@ unsigned find_get_pages(struct address_space *mapping, pgoff_t *start,
 	rcu_read_lock();
 	radix_tree_for_each_slot(slot, &mapping->page_tree, &iter, *start) {
 		struct page *head, *page;
+
+		if (iter.index > end)
+			break;
 repeat:
 		page = radix_tree_deref_slot(slot);
 		if (unlikely(!page))
@@ -1502,15 +1510,25 @@ unsigned find_get_pages(struct address_space *mapping, pgoff_t *start,
 		}
 
 		pages[ret] = page;
-		if (++ret == nr_pages)
-			break;
+		if (++ret == nr_pages) {
+			*start = pages[ret - 1]->index + 1;
+			goto out;
+		}
 	}
 
+	/*
+	 * We come here when there is no page beyond @end. We take care to not
+	 * overflow the index @start as it confuses some of the callers. This
+	 * breaks the iteration when there is page at index -1 but that is
+	 * already broken anyway.
+	 */
+	if (end == (pgoff_t)-1)
+		*start = (pgoff_t)-1;
+	else
+		*start = end + 1;
+out:
 	rcu_read_unlock();
 
-	if (ret)
-		*start = pages[ret - 1]->index + 1;
-
 	return ret;
 }
 
diff --git a/mm/swap.c b/mm/swap.c
index 368d627cf279..804c9867af96 100644
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -940,29 +940,35 @@ void pagevec_remove_exceptionals(struct pagevec *pvec)
 }
 
 /**
- * pagevec_lookup - gang pagecache lookup
+ * pagevec_lookup_range - gang pagecache lookup
  * @pvec:	Where the resulting pages are placed
  * @mapping:	The address_space to search
  * @start:	The starting page index
+ * @end:	The final page index
  * @nr_pages:	The maximum number of pages
  *
- * pagevec_lookup() will search for and return a group of up to @nr_pages pages
- * in the mapping.  The pages are placed in @pvec.  pagevec_lookup() takes a
+ * pagevec_lookup_range() will search for and return a group of up to @nr_pages
+ * pages in the mapping starting from index @start and upto index @end
+ * (inclusive).  The pages are placed in @pvec.  pagevec_lookup() takes a
  * reference against the pages in @pvec.
  *
  * The search returns a group of mapping-contiguous pages with ascending
  * indexes.  There may be holes in the indices due to not-present pages. We
  * also update @start to index the next page for the traversal.
  *
- * pagevec_lookup() returns the number of pages which were found.
+ * pagevec_lookup_range() returns the number of pages which were found. If this
+ * number is smaller than @nr_pages, the end of specified range has been
+ * reached.
  */
-unsigned pagevec_lookup(struct pagevec *pvec, struct address_space *mapping,
-		pgoff_t *start, unsigned nr_pages)
+unsigned pagevec_lookup_range(struct pagevec *pvec,
+		struct address_space *mapping, pgoff_t *start, pgoff_t end,
+		unsigned nr_pages)
 {
-	pvec->nr = find_get_pages(mapping, start, nr_pages, pvec->pages);
+	pvec->nr = find_get_pages_range(mapping, start, end, nr_pages,
+					pvec->pages);
 	return pagevec_count(pvec);
 }
-EXPORT_SYMBOL(pagevec_lookup);
+EXPORT_SYMBOL(pagevec_lookup_range);
 
 unsigned pagevec_lookup_tag(struct pagevec *pvec, struct address_space *mapping,
 		pgoff_t *index, int tag, unsigned nr_pages)
-- 
2.12.3

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 08/35] fs: Fix performance regression in clean_bdev_aliases()
  2017-06-01  9:32 [PATCH 00/35 v1] pagevec API cleanups Jan Kara
                   ` (6 preceding siblings ...)
  2017-06-01  9:32 ` [PATCH 07/35] mm: Implement find_get_pages_range() Jan Kara
@ 2017-06-01  9:32 ` Jan Kara
  2017-06-01  9:32 ` [PATCH 09/35] ext4: Use pagevec_lookup_range() in ext4_find_unwritten_pgoff() Jan Kara
                   ` (28 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Jan Kara @ 2017-06-01  9:32 UTC (permalink / raw)
  To: linux-mm
  Cc: Hugh Dickins, David Howells, linux-afs, Ryusuke Konishi,
	linux-nilfs, Bob Peterson, cluster-devel, Jaegeuk Kim,
	linux-f2fs-devel, tytso, linux-ext4, Ilya Dryomov, Yan, Zheng,
	ceph-devel, linux-btrfs, David Sterba, Darrick J . Wong,
	linux-xfs, Nadia Yvette Chambers, Jan Kara

Commit e64855c6cfaa "fs: Add helper to clean bdev aliases under a bh and
use it" added a wrapper for clean_bdev_aliases() that invalidates bdev
aliases underlying a single buffer head. However this has caused a
performance regression for bonnie++ benchmark on ext4 filesystem when
delayed allocation is turned off (ext3 mode) - average of 3 runs:

Hmean SeqOut Char  164787.55 (  0.00%) 107189.06 (-34.95%)
Hmean SeqOut Block 219883.89 (  0.00%) 168870.32 (-23.20%)

The reason for this regression is that clean_bdev_aliases() is slower
when called for a single block because pagevec_lookup() it uses will end
up iterating through the radix tree until it finds a page (which may
take a while) but we are only interested whether there's a page at a
particular index.

Fix the problem by using pagevec_lookup_range() instead which avoids the
needless iteration.

Fixes: e64855c6cfaa0a80c1b71c5f647cb792dc436668
Signed-off-by: Jan Kara <jack@suse.cz>
---
 fs/buffer.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/fs/buffer.c b/fs/buffer.c
index fe0ee01c5a44..d63b22e50f38 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -1632,19 +1632,18 @@ void clean_bdev_aliases(struct block_device *bdev, sector_t block, sector_t len)
 	struct pagevec pvec;
 	pgoff_t index = block >> (PAGE_SHIFT - bd_inode->i_blkbits);
 	pgoff_t end;
-	int i;
+	int i, count;
 	struct buffer_head *bh;
 	struct buffer_head *head;
 
 	end = (block + len - 1) >> (PAGE_SHIFT - bd_inode->i_blkbits);
 	pagevec_init(&pvec, 0);
-	while (index <= end && pagevec_lookup(&pvec, bd_mapping, &index,
-			min(end - index, (pgoff_t)PAGEVEC_SIZE - 1) + 1)) {
-		for (i = 0; i < pagevec_count(&pvec); i++) {
+	while (pagevec_lookup_range(&pvec, bd_mapping, &index, end,
+				    PAGEVEC_SIZE)) {
+		count = pagevec_count(&pvec);
+		for (i = 0; i < count; i++) {
 			struct page *page = pvec.pages[i];
 
-			if (page->index > end)
-				break;
 			if (!page_has_buffers(page))
 				continue;
 			/*
@@ -1674,6 +1673,9 @@ void clean_bdev_aliases(struct block_device *bdev, sector_t block, sector_t len)
 		}
 		pagevec_release(&pvec);
 		cond_resched();
+		/* End of range already reached? */
+		if (index > end || !index)
+			break;
 	}
 }
 EXPORT_SYMBOL(clean_bdev_aliases);
-- 
2.12.3

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 09/35] ext4: Use pagevec_lookup_range() in ext4_find_unwritten_pgoff()
  2017-06-01  9:32 [PATCH 00/35 v1] pagevec API cleanups Jan Kara
                   ` (7 preceding siblings ...)
  2017-06-01  9:32 ` [PATCH 08/35] fs: Fix performance regression in clean_bdev_aliases() Jan Kara
@ 2017-06-01  9:32 ` Jan Kara
  2017-06-01  9:32 ` [PATCH 10/35] ext4: Use pagevec_lookup_range() in writeback code Jan Kara
                   ` (27 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Jan Kara @ 2017-06-01  9:32 UTC (permalink / raw)
  To: linux-mm
  Cc: Hugh Dickins, David Howells, linux-afs, Ryusuke Konishi,
	linux-nilfs, Bob Peterson, cluster-devel, Jaegeuk Kim,
	linux-f2fs-devel, tytso, linux-ext4, Ilya Dryomov, Yan, Zheng,
	ceph-devel, linux-btrfs, David Sterba, Darrick J . Wong,
	linux-xfs, Nadia Yvette Chambers, Jan Kara

Use pagevec_lookup_range() in ext4_find_unwritten_pgoff() since we are
interested only in pages in the given range. Simplify the logic as a
result of not getting pages out of range and index getting automatically
advanced.

CC: linux-ext4@vger.kernel.org
CC: "Theodore Ts'o" <tytso@mit.edu>
Signed-off-by: Jan Kara <jack@suse.cz>
---
 fs/ext4/file.c | 14 ++++----------
 1 file changed, 4 insertions(+), 10 deletions(-)

diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index ddca17c7875a..6821070a388b 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -478,12 +478,11 @@ static int ext4_find_unwritten_pgoff(struct inode *inode,
 
 	pagevec_init(&pvec, 0);
 	do {
-		int i, num;
+		int i;
 		unsigned long nr_pages;
 
-		num = min_t(pgoff_t, end - index, PAGEVEC_SIZE);
-		nr_pages = pagevec_lookup(&pvec, inode->i_mapping, &index,
-					  (pgoff_t)num);
+		nr_pages = pagevec_lookup_range(&pvec, inode->i_mapping,
+					&index, end, PAGEVEC_SIZE);
 		if (nr_pages == 0)
 			break;
 
@@ -502,9 +501,6 @@ static int ext4_find_unwritten_pgoff(struct inode *inode,
 				goto out;
 			}
 
-			if (page->index > end)
-				goto out;
-
 			lock_page(page);
 
 			if (unlikely(page->mapping != inode->i_mapping)) {
@@ -544,12 +540,10 @@ static int ext4_find_unwritten_pgoff(struct inode *inode,
 			unlock_page(page);
 		}
 
-		/* The no. of pages is less than our desired, we are done. */
-		if (nr_pages < num)
-			break;
 		pagevec_release(&pvec);
 	} while (index <= end);
 
+	/* There are no pages upto endoff - that would be a hole in there. */
 	if (whence == SEEK_HOLE && lastoff < endoff) {
 		found = 1;
 		*offset = lastoff;
-- 
2.12.3

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 10/35] ext4: Use pagevec_lookup_range() in writeback code
  2017-06-01  9:32 [PATCH 00/35 v1] pagevec API cleanups Jan Kara
                   ` (8 preceding siblings ...)
  2017-06-01  9:32 ` [PATCH 09/35] ext4: Use pagevec_lookup_range() in ext4_find_unwritten_pgoff() Jan Kara
@ 2017-06-01  9:32 ` Jan Kara
  2017-06-01  9:32 ` [PATCH 11/35] hugetlbfs: Use pagevec_lookup_range() in remove_inode_hugepages() Jan Kara
                   ` (26 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Jan Kara @ 2017-06-01  9:32 UTC (permalink / raw)
  To: linux-mm
  Cc: Hugh Dickins, David Howells, linux-afs, Ryusuke Konishi,
	linux-nilfs, Bob Peterson, cluster-devel, Jaegeuk Kim,
	linux-f2fs-devel, tytso, linux-ext4, Ilya Dryomov, Yan, Zheng,
	ceph-devel, linux-btrfs, David Sterba, Darrick J . Wong,
	linux-xfs, Nadia Yvette Chambers, Jan Kara

Both occurences of pagevec_lookup() actually want only pages from a
given range. Use pagevec_lookup_range() for the lookup.

CC: "Theodore Ts'o" <tytso@mit.edu>
CC: linux-ext4@vger.kernel.org
Signed-off-by: Jan Kara <jack@suse.cz>
---
 fs/ext4/inode.c | 12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 784f41328dc8..59d82530d269 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -1670,13 +1670,13 @@ static void mpage_release_unused_pages(struct mpage_da_data *mpd,
 
 	pagevec_init(&pvec, 0);
 	while (index <= end) {
-		nr_pages = pagevec_lookup(&pvec, mapping, &index, PAGEVEC_SIZE);
+		nr_pages = pagevec_lookup_range(&pvec, mapping, &index, end,
+						PAGEVEC_SIZE);
 		if (nr_pages == 0)
 			break;
 		for (i = 0; i < nr_pages; i++) {
 			struct page *page = pvec.pages[i];
-			if (page->index > end)
-				break;
+
 			BUG_ON(!PageLocked(page));
 			BUG_ON(PageWriteback(page));
 			if (invalidate) {
@@ -2283,15 +2283,13 @@ static int mpage_map_and_submit_buffers(struct mpage_da_data *mpd)
 
 	pagevec_init(&pvec, 0);
 	while (start <= end) {
-		nr_pages = pagevec_lookup(&pvec, inode->i_mapping, &start,
-					  PAGEVEC_SIZE);
+		nr_pages = pagevec_lookup_range(&pvec, inode->i_mapping,
+						&start, end, PAGEVEC_SIZE);
 		if (nr_pages == 0)
 			break;
 		for (i = 0; i < nr_pages; i++) {
 			struct page *page = pvec.pages[i];
 
-			if (page->index > end)
-				break;
 			bh = head = page_buffers(page);
 			do {
 				if (lblk < mpd->map.m_lblk)
-- 
2.12.3

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 11/35] hugetlbfs: Use pagevec_lookup_range() in remove_inode_hugepages()
  2017-06-01  9:32 [PATCH 00/35 v1] pagevec API cleanups Jan Kara
                   ` (9 preceding siblings ...)
  2017-06-01  9:32 ` [PATCH 10/35] ext4: Use pagevec_lookup_range() in writeback code Jan Kara
@ 2017-06-01  9:32 ` Jan Kara
  2017-06-01  9:32 ` [PATCH 12/35] xfs: Use pagevec_lookup_range() in xfs_find_get_desired_pgoff() Jan Kara
                   ` (25 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Jan Kara @ 2017-06-01  9:32 UTC (permalink / raw)
  To: linux-mm
  Cc: Hugh Dickins, David Howells, linux-afs, Ryusuke Konishi,
	linux-nilfs, Bob Peterson, cluster-devel, Jaegeuk Kim,
	linux-f2fs-devel, tytso, linux-ext4, Ilya Dryomov, Yan, Zheng,
	ceph-devel, linux-btrfs, David Sterba, Darrick J . Wong,
	linux-xfs, Nadia Yvette Chambers, Jan Kara

We want only pages from given range in remove_inode_hugepages(). Use
pagevec_lookup_range() instead of pagevec_lookup().

CC: Nadia Yvette Chambers <nyc@holomorphy.com>
Signed-off-by: Jan Kara <jack@suse.cz>
---
 fs/hugetlbfs/inode.c | 18 ++----------------
 1 file changed, 2 insertions(+), 16 deletions(-)

diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index 372fc8aac38e..99885f9b9d56 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -403,7 +403,6 @@ static void remove_inode_hugepages(struct inode *inode, loff_t lstart,
 	struct pagevec pvec;
 	pgoff_t next, index;
 	int i, freed = 0;
-	long lookup_nr = PAGEVEC_SIZE;
 	bool truncate_op = (lend == LLONG_MAX);
 
 	memset(&pseudo_vma, 0, sizeof(struct vm_area_struct));
@@ -412,30 +411,17 @@ static void remove_inode_hugepages(struct inode *inode, loff_t lstart,
 	next = start;
 	while (next < end) {
 		/*
-		 * Don't grab more pages than the number left in the range.
-		 */
-		if (end - next < lookup_nr)
-			lookup_nr = end - next;
-
-		/*
 		 * When no more pages are found, we are done.
 		 */
-		if (!pagevec_lookup(&pvec, mapping, &next, lookup_nr))
+		if (!pagevec_lookup_range(&pvec, mapping, &next, end - 1,
+					  PAGEVEC_SIZE))
 			break;
 
 		for (i = 0; i < pagevec_count(&pvec); ++i) {
 			struct page *page = pvec.pages[i];
 			u32 hash;
 
-			/*
-			 * The page (index) could be beyond end.  This is
-			 * only possible in the punch hole case as end is
-			 * max page offset in the truncate case.
-			 */
 			index = page->index;
-			if (index >= end)
-				break;
-
 			hash = hugetlb_fault_mutex_hash(h, current->mm,
 							&pseudo_vma,
 							mapping, index, 0);
-- 
2.12.3

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 12/35] xfs: Use pagevec_lookup_range() in xfs_find_get_desired_pgoff()
  2017-06-01  9:32 [PATCH 00/35 v1] pagevec API cleanups Jan Kara
                   ` (10 preceding siblings ...)
  2017-06-01  9:32 ` [PATCH 11/35] hugetlbfs: Use pagevec_lookup_range() in remove_inode_hugepages() Jan Kara
@ 2017-06-01  9:32 ` Jan Kara
  2017-06-01  9:32 ` [PATCH 13/35] mm: Remove nr_pages argument from pagevec_lookup{,_range}() Jan Kara
                   ` (24 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Jan Kara @ 2017-06-01  9:32 UTC (permalink / raw)
  To: linux-mm
  Cc: Hugh Dickins, David Howells, linux-afs, Ryusuke Konishi,
	linux-nilfs, Bob Peterson, cluster-devel, Jaegeuk Kim,
	linux-f2fs-devel, tytso, linux-ext4, Ilya Dryomov, Yan, Zheng,
	ceph-devel, linux-btrfs, David Sterba, Darrick J . Wong,
	linux-xfs, Nadia Yvette Chambers, Jan Kara

We want only pages from given range in xfs_find_get_desired_pgoff(). Use
pagevec_lookup_range() instead of pagevec_lookup() and remove
unnecessary code. Note that the check for getting less pages than
desired can be removed because index gets updated by
pagevec_lookup_range().

CC: Darrick J. Wong <darrick.wong@oracle.com>
CC: linux-xfs@vger.kernel.org
Signed-off-by: Jan Kara <jack@suse.cz>
---
 fs/xfs/xfs_file.c | 16 ++--------------
 1 file changed, 2 insertions(+), 14 deletions(-)

diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index 487342078fc7..f9343dac7ff9 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -1045,13 +1045,11 @@ xfs_find_get_desired_pgoff(
 	endoff = XFS_FSB_TO_B(mp, map->br_startoff + map->br_blockcount);
 	end = (endoff - 1) >> PAGE_SHIFT;
 	do {
-		int		want;
 		unsigned	nr_pages;
 		unsigned int	i;
 
-		want = min_t(pgoff_t, end - index, PAGEVEC_SIZE - 1) + 1;
-		nr_pages = pagevec_lookup(&pvec, inode->i_mapping, &index,
-					  want);
+		nr_pages = pagevec_lookup_range(&pvec, inode->i_mapping,
+						&index, end, PAGEVEC_SIZE);
 		if (nr_pages == 0)
 			break;
 
@@ -1075,9 +1073,6 @@ xfs_find_get_desired_pgoff(
 				*offset = lastoff;
 				goto out;
 			}
-			/* Searching done if the page index is out of range. */
-			if (page->index > end)
-				goto out;
 
 			lock_page(page);
 			/*
@@ -1117,13 +1112,6 @@ xfs_find_get_desired_pgoff(
 			unlock_page(page);
 		}
 
-		/*
-		 * The number of returned pages less than our desired, search
-		 * done.
-		 */
-		if (nr_pages < want)
-			break;
-
 		pagevec_release(&pvec);
 	} while (index <= end);
 
-- 
2.12.3

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 13/35] mm: Remove nr_pages argument from pagevec_lookup{,_range}()
  2017-06-01  9:32 [PATCH 00/35 v1] pagevec API cleanups Jan Kara
                   ` (11 preceding siblings ...)
  2017-06-01  9:32 ` [PATCH 12/35] xfs: Use pagevec_lookup_range() in xfs_find_get_desired_pgoff() Jan Kara
@ 2017-06-01  9:32 ` Jan Kara
  2017-06-01  9:32 ` [PATCH 14/35] mm: Implement find_get_pages_range_tag() Jan Kara
                   ` (23 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Jan Kara @ 2017-06-01  9:32 UTC (permalink / raw)
  To: linux-mm
  Cc: Hugh Dickins, David Howells, linux-afs, Ryusuke Konishi,
	linux-nilfs, Bob Peterson, cluster-devel, Jaegeuk Kim,
	linux-f2fs-devel, tytso, linux-ext4, Ilya Dryomov, Yan, Zheng,
	ceph-devel, linux-btrfs, David Sterba, Darrick J . Wong,
	linux-xfs, Nadia Yvette Chambers, Jan Kara

All users of pagevec_lookup() and pagevec_lookup_range() now pass
PAGEVEC_SIZE as a desired number of pages. Just drop the argument.

Signed-off-by: Jan Kara <jack@suse.cz>
---
 fs/buffer.c             | 3 +--
 fs/ext4/file.c          | 2 +-
 fs/ext4/inode.c         | 5 ++---
 fs/fscache/page.c       | 2 +-
 fs/hugetlbfs/inode.c    | 3 +--
 fs/nilfs2/page.c        | 2 +-
 fs/xfs/xfs_file.c       | 2 +-
 include/linux/pagevec.h | 7 +++----
 mm/swap.c               | 5 ++---
 9 files changed, 13 insertions(+), 18 deletions(-)

diff --git a/fs/buffer.c b/fs/buffer.c
index d63b22e50f38..89605cb42a55 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -1638,8 +1638,7 @@ void clean_bdev_aliases(struct block_device *bdev, sector_t block, sector_t len)
 
 	end = (block + len - 1) >> (PAGE_SHIFT - bd_inode->i_blkbits);
 	pagevec_init(&pvec, 0);
-	while (pagevec_lookup_range(&pvec, bd_mapping, &index, end,
-				    PAGEVEC_SIZE)) {
+	while (pagevec_lookup_range(&pvec, bd_mapping, &index, end)) {
 		count = pagevec_count(&pvec);
 		for (i = 0; i < count; i++) {
 			struct page *page = pvec.pages[i];
diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index 6821070a388b..2d9a198026e5 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -482,7 +482,7 @@ static int ext4_find_unwritten_pgoff(struct inode *inode,
 		unsigned long nr_pages;
 
 		nr_pages = pagevec_lookup_range(&pvec, inode->i_mapping,
-					&index, end, PAGEVEC_SIZE);
+					&index, end);
 		if (nr_pages == 0)
 			break;
 
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 59d82530d269..ace4bb9073d8 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -1670,8 +1670,7 @@ static void mpage_release_unused_pages(struct mpage_da_data *mpd,
 
 	pagevec_init(&pvec, 0);
 	while (index <= end) {
-		nr_pages = pagevec_lookup_range(&pvec, mapping, &index, end,
-						PAGEVEC_SIZE);
+		nr_pages = pagevec_lookup_range(&pvec, mapping, &index, end);
 		if (nr_pages == 0)
 			break;
 		for (i = 0; i < nr_pages; i++) {
@@ -2284,7 +2283,7 @@ static int mpage_map_and_submit_buffers(struct mpage_da_data *mpd)
 	pagevec_init(&pvec, 0);
 	while (start <= end) {
 		nr_pages = pagevec_lookup_range(&pvec, inode->i_mapping,
-						&start, end, PAGEVEC_SIZE);
+						&start, end);
 		if (nr_pages == 0)
 			break;
 		for (i = 0; i < nr_pages; i++) {
diff --git a/fs/fscache/page.c b/fs/fscache/page.c
index 83018861dcd2..0ad3fd3ad0b4 100644
--- a/fs/fscache/page.c
+++ b/fs/fscache/page.c
@@ -1178,7 +1178,7 @@ void __fscache_uncache_all_inode_pages(struct fscache_cookie *cookie,
 	pagevec_init(&pvec, 0);
 	next = 0;
 	do {
-		if (!pagevec_lookup(&pvec, mapping, &next, PAGEVEC_SIZE))
+		if (!pagevec_lookup(&pvec, mapping, &next))
 			break;
 		for (i = 0; i < pagevec_count(&pvec); i++) {
 			struct page *page = pvec.pages[i];
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index 99885f9b9d56..461e01500e60 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -413,8 +413,7 @@ static void remove_inode_hugepages(struct inode *inode, loff_t lstart,
 		/*
 		 * When no more pages are found, we are done.
 		 */
-		if (!pagevec_lookup_range(&pvec, mapping, &next, end - 1,
-					  PAGEVEC_SIZE))
+		if (!pagevec_lookup_range(&pvec, mapping, &next, end - 1))
 			break;
 
 		for (i = 0; i < pagevec_count(&pvec); ++i) {
diff --git a/fs/nilfs2/page.c b/fs/nilfs2/page.c
index 382a36c72d72..8616c46d33da 100644
--- a/fs/nilfs2/page.c
+++ b/fs/nilfs2/page.c
@@ -312,7 +312,7 @@ void nilfs_copy_back_pages(struct address_space *dmap,
 
 	pagevec_init(&pvec, 0);
 repeat:
-	n = pagevec_lookup(&pvec, smap, &index, PAGEVEC_SIZE);
+	n = pagevec_lookup(&pvec, smap, &index);
 	if (!n)
 		return;
 
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index f9343dac7ff9..a7abc981e4a9 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -1049,7 +1049,7 @@ xfs_find_get_desired_pgoff(
 		unsigned int	i;
 
 		nr_pages = pagevec_lookup_range(&pvec, inode->i_mapping,
-						&index, end, PAGEVEC_SIZE);
+						&index, end);
 		if (nr_pages == 0)
 			break;
 
diff --git a/include/linux/pagevec.h b/include/linux/pagevec.h
index 7df056910437..4dcd5506f1ed 100644
--- a/include/linux/pagevec.h
+++ b/include/linux/pagevec.h
@@ -29,13 +29,12 @@ unsigned pagevec_lookup_entries(struct pagevec *pvec,
 void pagevec_remove_exceptionals(struct pagevec *pvec);
 unsigned pagevec_lookup_range(struct pagevec *pvec,
 			      struct address_space *mapping,
-			      pgoff_t *start, pgoff_t end, unsigned nr_pages);
+			      pgoff_t *start, pgoff_t end);
 static inline unsigned pagevec_lookup(struct pagevec *pvec,
 				      struct address_space *mapping,
-				      pgoff_t *start, unsigned nr_pages)
+				      pgoff_t *start)
 {
-	return pagevec_lookup_range(pvec, mapping, start, (pgoff_t)-1,
-				    nr_pages);
+	return pagevec_lookup_range(pvec, mapping, start, (pgoff_t)-1);
 }
 
 unsigned pagevec_lookup_tag(struct pagevec *pvec,
diff --git a/mm/swap.c b/mm/swap.c
index 804c9867af96..a07a0105154b 100644
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -961,10 +961,9 @@ void pagevec_remove_exceptionals(struct pagevec *pvec)
  * reached.
  */
 unsigned pagevec_lookup_range(struct pagevec *pvec,
-		struct address_space *mapping, pgoff_t *start, pgoff_t end,
-		unsigned nr_pages)
+		struct address_space *mapping, pgoff_t *start, pgoff_t end)
 {
-	pvec->nr = find_get_pages_range(mapping, start, end, nr_pages,
+	pvec->nr = find_get_pages_range(mapping, start, end, PAGEVEC_SIZE,
 					pvec->pages);
 	return pagevec_count(pvec);
 }
-- 
2.12.3

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 14/35] mm: Implement find_get_pages_range_tag()
  2017-06-01  9:32 [PATCH 00/35 v1] pagevec API cleanups Jan Kara
                   ` (12 preceding siblings ...)
  2017-06-01  9:32 ` [PATCH 13/35] mm: Remove nr_pages argument from pagevec_lookup{,_range}() Jan Kara
@ 2017-06-01  9:32 ` Jan Kara
  2017-06-01  9:32 ` [PATCH 15/35] btrfs: Use pagevec_lookup_range_tag() Jan Kara
                   ` (22 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Jan Kara @ 2017-06-01  9:32 UTC (permalink / raw)
  To: linux-mm
  Cc: Hugh Dickins, David Howells, linux-afs, Ryusuke Konishi,
	linux-nilfs, Bob Peterson, cluster-devel, Jaegeuk Kim,
	linux-f2fs-devel, tytso, linux-ext4, Ilya Dryomov, Yan, Zheng,
	ceph-devel, linux-btrfs, David Sterba, Darrick J . Wong,
	linux-xfs, Nadia Yvette Chambers, Jan Kara

Implement a variant of find_get_pages_tag() that stops iterating at
given index. Lots of users of this function (through pagevec_lookup())
actually want a range lookup and all of them are currently open-coding
this.

Also create corresponding pagevec_lookup_range_tag() function.

Signed-off-by: Jan Kara <jack@suse.cz>
---
 include/linux/pagemap.h | 12 ++++++++++--
 include/linux/pagevec.h | 11 +++++++++--
 mm/filemap.c            | 33 ++++++++++++++++++++++++---------
 mm/swap.c               |  9 +++++----
 4 files changed, 48 insertions(+), 17 deletions(-)

diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
index 2bb5e636a8c8..a2d3534a514f 100644
--- a/include/linux/pagemap.h
+++ b/include/linux/pagemap.h
@@ -348,8 +348,16 @@ static inline unsigned find_get_pages(struct address_space *mapping,
 }
 unsigned find_get_pages_contig(struct address_space *mapping, pgoff_t start,
 			       unsigned int nr_pages, struct page **pages);
-unsigned find_get_pages_tag(struct address_space *mapping, pgoff_t *index,
-			int tag, unsigned int nr_pages, struct page **pages);
+unsigned find_get_pages_range_tag(struct address_space *mapping, pgoff_t *index,
+			pgoff_t end, int tag, unsigned int nr_pages,
+			struct page **pages);
+static inline unsigned find_get_pages_tag(struct address_space *mapping,
+			pgoff_t *index, int tag, unsigned int nr_pages,
+			struct page **pages)
+{
+	return find_get_pages_range_tag(mapping, index, (pgoff_t)-1, tag,
+					nr_pages, pages);
+}
 unsigned find_get_entries_tag(struct address_space *mapping, pgoff_t start,
 			int tag, unsigned int nr_entries,
 			struct page **entries, pgoff_t *indices);
diff --git a/include/linux/pagevec.h b/include/linux/pagevec.h
index 4dcd5506f1ed..371edacc10d5 100644
--- a/include/linux/pagevec.h
+++ b/include/linux/pagevec.h
@@ -37,9 +37,16 @@ static inline unsigned pagevec_lookup(struct pagevec *pvec,
 	return pagevec_lookup_range(pvec, mapping, start, (pgoff_t)-1);
 }
 
-unsigned pagevec_lookup_tag(struct pagevec *pvec,
+unsigned pagevec_lookup_range_tag(struct pagevec *pvec,
+		struct address_space *mapping, pgoff_t *index, pgoff_t end,
+		int tag, unsigned nr_pages);
+static inline unsigned pagevec_lookup_tag(struct pagevec *pvec,
 		struct address_space *mapping, pgoff_t *index, int tag,
-		unsigned nr_pages);
+		unsigned nr_pages)
+{
+	return pagevec_lookup_range_tag(pvec, mapping, index, (pgoff_t)-1, tag,
+					nr_pages);
+}
 
 static inline void pagevec_init(struct pagevec *pvec, int cold)
 {
diff --git a/mm/filemap.c b/mm/filemap.c
index 2693f87a7968..56af68f6a375 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -1612,9 +1612,10 @@ unsigned find_get_pages_contig(struct address_space *mapping, pgoff_t index,
 EXPORT_SYMBOL(find_get_pages_contig);
 
 /**
- * find_get_pages_tag - find and return pages that match @tag
+ * find_get_pages_range_tag - find and return pages in given range matching @tag
  * @mapping:	the address_space to search
  * @index:	the starting page index
+ * @end:	The final page index (inclusive)
  * @tag:	the tag index
  * @nr_pages:	the maximum number of pages
  * @pages:	where the resulting pages are placed
@@ -1622,8 +1623,9 @@ EXPORT_SYMBOL(find_get_pages_contig);
  * Like find_get_pages, except we only return pages which are tagged with
  * @tag.   We update @index to index the next page for the traversal.
  */
-unsigned find_get_pages_tag(struct address_space *mapping, pgoff_t *index,
-			int tag, unsigned int nr_pages, struct page **pages)
+unsigned find_get_pages_range_tag(struct address_space *mapping, pgoff_t *index,
+			pgoff_t end, int tag, unsigned int nr_pages,
+			struct page **pages)
 {
 	struct radix_tree_iter iter;
 	void **slot;
@@ -1636,6 +1638,9 @@ unsigned find_get_pages_tag(struct address_space *mapping, pgoff_t *index,
 	radix_tree_for_each_tagged(slot, &mapping->page_tree,
 				   &iter, *index, tag) {
 		struct page *head, *page;
+
+		if (iter.index > end)
+			break;
 repeat:
 		page = radix_tree_deref_slot(slot);
 		if (unlikely(!page))
@@ -1677,18 +1682,28 @@ unsigned find_get_pages_tag(struct address_space *mapping, pgoff_t *index,
 		}
 
 		pages[ret] = page;
-		if (++ret == nr_pages)
-			break;
+		if (++ret == nr_pages) {
+			*index = pages[ret - 1]->index + 1;
+			goto out;
+		}
 	}
 
+	/*
+	 * We come here when we got at @end. We take care to not overflow the
+	 * index @index as it confuses some of the callers. This breaks the
+	 * iteration when there is page at index -1 but that is already broken
+	 * anyway.
+	 */
+	if (end == (pgoff_t)-1)
+		*index = (pgoff_t)-1;
+	else
+		*index = end + 1;
+out:
 	rcu_read_unlock();
 
-	if (ret)
-		*index = pages[ret - 1]->index + 1;
-
 	return ret;
 }
-EXPORT_SYMBOL(find_get_pages_tag);
+EXPORT_SYMBOL(find_get_pages_range_tag);
 
 /**
  * find_get_entries_tag - find and return entries that match @tag
diff --git a/mm/swap.c b/mm/swap.c
index a07a0105154b..4714d07965c1 100644
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -969,14 +969,15 @@ unsigned pagevec_lookup_range(struct pagevec *pvec,
 }
 EXPORT_SYMBOL(pagevec_lookup_range);
 
-unsigned pagevec_lookup_tag(struct pagevec *pvec, struct address_space *mapping,
-		pgoff_t *index, int tag, unsigned nr_pages)
+unsigned pagevec_lookup_range_tag(struct pagevec *pvec,
+		struct address_space *mapping, pgoff_t *index, pgoff_t end,
+		int tag, unsigned nr_pages)
 {
-	pvec->nr = find_get_pages_tag(mapping, index, tag,
+	pvec->nr = find_get_pages_range_tag(mapping, index, end, tag,
 					nr_pages, pvec->pages);
 	return pagevec_count(pvec);
 }
-EXPORT_SYMBOL(pagevec_lookup_tag);
+EXPORT_SYMBOL(pagevec_lookup_range_tag);
 
 /*
  * Perform any setup for the swap system
-- 
2.12.3

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 15/35] btrfs: Use pagevec_lookup_range_tag()
  2017-06-01  9:32 [PATCH 00/35 v1] pagevec API cleanups Jan Kara
                   ` (13 preceding siblings ...)
  2017-06-01  9:32 ` [PATCH 14/35] mm: Implement find_get_pages_range_tag() Jan Kara
@ 2017-06-01  9:32 ` Jan Kara
  2017-06-01  9:32 ` [PATCH 16/35] ceph: " Jan Kara
                   ` (21 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Jan Kara @ 2017-06-01  9:32 UTC (permalink / raw)
  To: linux-mm
  Cc: Hugh Dickins, David Howells, linux-afs, Ryusuke Konishi,
	linux-nilfs, Bob Peterson, cluster-devel, Jaegeuk Kim,
	linux-f2fs-devel, tytso, linux-ext4, Ilya Dryomov, Yan, Zheng,
	ceph-devel, linux-btrfs, David Sterba, Darrick J . Wong,
	linux-xfs, Nadia Yvette Chambers, Jan Kara

We want only pages from given range in btree_write_cache_pages() and
extent_write_cache_pages(). Use pagevec_lookup_range_tag() instead of
pagevec_lookup_tag() and remove unnecessary code.

CC: linux-btrfs@vger.kernel.org
CC: David Sterba <dsterba@suse.com>
Signed-off-by: Jan Kara <jack@suse.cz>
---
 fs/btrfs/extent_io.c | 19 ++++---------------
 1 file changed, 4 insertions(+), 15 deletions(-)

diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index d8da3edf2ac3..6287eaba30ac 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -3837,8 +3837,8 @@ int btree_write_cache_pages(struct address_space *mapping,
 	if (wbc->sync_mode == WB_SYNC_ALL)
 		tag_pages_for_writeback(mapping, index, end);
 	while (!done && !nr_to_write_done && (index <= end) &&
-	       (nr_pages = pagevec_lookup_tag(&pvec, mapping, &index, tag,
-			min(end - index, (pgoff_t)PAGEVEC_SIZE-1) + 1))) {
+	       (nr_pages = pagevec_lookup_range_tag(&pvec, mapping, &index, end,
+			tag, PAGEVEC_SIZE))) {
 		unsigned i;
 
 		scanned = 1;
@@ -3848,11 +3848,6 @@ int btree_write_cache_pages(struct address_space *mapping,
 			if (!PagePrivate(page))
 				continue;
 
-			if (!wbc->range_cyclic && page->index > end) {
-				done = 1;
-				break;
-			}
-
 			spin_lock(&mapping->private_lock);
 			if (!PagePrivate(page)) {
 				spin_unlock(&mapping->private_lock);
@@ -3984,8 +3979,8 @@ static int extent_write_cache_pages(struct address_space *mapping,
 		tag_pages_for_writeback(mapping, index, end);
 	done_index = index;
 	while (!done && !nr_to_write_done && (index <= end) &&
-	       (nr_pages = pagevec_lookup_tag(&pvec, mapping, &index, tag,
-			min(end - index, (pgoff_t)PAGEVEC_SIZE-1) + 1))) {
+	       (nr_pages = pagevec_lookup_range_tag(&pvec, mapping, &index, end,
+			tag, PAGEVEC_SIZE))) {
 		unsigned i;
 
 		scanned = 1;
@@ -4010,12 +4005,6 @@ static int extent_write_cache_pages(struct address_space *mapping,
 				continue;
 			}
 
-			if (!wbc->range_cyclic && page->index > end) {
-				done = 1;
-				unlock_page(page);
-				continue;
-			}
-
 			if (wbc->sync_mode != WB_SYNC_NONE) {
 				if (PageWriteback(page))
 					flush_fn(data);
-- 
2.12.3

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 16/35] ceph: Use pagevec_lookup_range_tag()
  2017-06-01  9:32 [PATCH 00/35 v1] pagevec API cleanups Jan Kara
                   ` (14 preceding siblings ...)
  2017-06-01  9:32 ` [PATCH 15/35] btrfs: Use pagevec_lookup_range_tag() Jan Kara
@ 2017-06-01  9:32 ` Jan Kara
  2017-06-01  9:32 ` [PATCH 17/35] ext4: " Jan Kara
                   ` (20 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Jan Kara @ 2017-06-01  9:32 UTC (permalink / raw)
  To: linux-mm
  Cc: Hugh Dickins, David Howells, linux-afs, Ryusuke Konishi,
	linux-nilfs, Bob Peterson, cluster-devel, Jaegeuk Kim,
	linux-f2fs-devel, tytso, linux-ext4, Ilya Dryomov, Yan, Zheng,
	ceph-devel, linux-btrfs, David Sterba, Darrick J . Wong,
	linux-xfs, Nadia Yvette Chambers, Jan Kara

We want only pages from given range in ceph_writepages_start(). Use
pagevec_lookup_range_tag() instead of pagevec_lookup_tag() and remove
unnecessary code.

CC: Ilya Dryomov <idryomov@gmail.com>
CC: "Yan, Zheng" <zyan@redhat.com>
CC: ceph-devel@vger.kernel.org
Signed-off-by: Jan Kara <jack@suse.cz>
---
 fs/ceph/addr.c | 19 ++++---------------
 1 file changed, 4 insertions(+), 15 deletions(-)

diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c
index 1e71e6ca5ddf..0b7e56ae3b8c 100644
--- a/fs/ceph/addr.c
+++ b/fs/ceph/addr.c
@@ -841,21 +841,16 @@ static int ceph_writepages_start(struct address_space *mapping,
 		struct page **pages = NULL, **data_pages;
 		mempool_t *pool = NULL;	/* Becomes non-null if mempool used */
 		struct page *page;
-		int want;
 		u64 offset = 0, len = 0;
 
 		max_pages = max_pages_ever;
 
 get_more_pages:
 		first = -1;
-		want = min(end - index,
-			   min((pgoff_t)PAGEVEC_SIZE,
-			       max_pages - (pgoff_t)locked_pages) - 1)
-			+ 1;
-		pvec_pages = pagevec_lookup_tag(&pvec, mapping, &index,
-						PAGECACHE_TAG_DIRTY,
-						want);
-		dout("pagevec_lookup_tag got %d\n", pvec_pages);
+		pvec_pages = pagevec_lookup_range_tag(&pvec, mapping, &index,
+						end, PAGECACHE_TAG_DIRTY,
+						PAGEVEC_SIZE);
+		dout("pagevec_lookup_range_tag got %d\n", pvec_pages);
 		if (!pvec_pages && !locked_pages)
 			break;
 		for (i = 0; i < pvec_pages && locked_pages < max_pages; i++) {
@@ -873,12 +868,6 @@ static int ceph_writepages_start(struct address_space *mapping,
 				unlock_page(page);
 				break;
 			}
-			if (!wbc->range_cyclic && page->index > end) {
-				dout("end of range %p\n", page);
-				done = 1;
-				unlock_page(page);
-				break;
-			}
 			if (strip_unit_end && (page->index > strip_unit_end)) {
 				dout("end of strip unit %p\n", page);
 				unlock_page(page);
-- 
2.12.3

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 17/35] ext4: Use pagevec_lookup_range_tag()
  2017-06-01  9:32 [PATCH 00/35 v1] pagevec API cleanups Jan Kara
                   ` (15 preceding siblings ...)
  2017-06-01  9:32 ` [PATCH 16/35] ceph: " Jan Kara
@ 2017-06-01  9:32 ` Jan Kara
  2017-06-01  9:32 ` [PATCH 18/35] f2fs: " Jan Kara
                   ` (19 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Jan Kara @ 2017-06-01  9:32 UTC (permalink / raw)
  To: linux-mm
  Cc: Hugh Dickins, David Howells, linux-afs, Ryusuke Konishi,
	linux-nilfs, Bob Peterson, cluster-devel, Jaegeuk Kim,
	linux-f2fs-devel, tytso, linux-ext4, Ilya Dryomov, Yan, Zheng,
	ceph-devel, linux-btrfs, David Sterba, Darrick J . Wong,
	linux-xfs, Nadia Yvette Chambers, Jan Kara

We want only pages from given range in ext4_writepages(). Use
pagevec_lookup_range_tag() instead of pagevec_lookup_tag() and remove
unnecessary code.

CC: "Theodore Ts'o" <tytso@mit.edu>
CC: linux-ext4@vger.kernel.org
Signed-off-by: Jan Kara <jack@suse.cz>
---
 fs/ext4/inode.c | 14 ++------------
 1 file changed, 2 insertions(+), 12 deletions(-)

diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index ace4bb9073d8..050fba2d12c2 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -2555,8 +2555,8 @@ static int mpage_prepare_extent_to_map(struct mpage_da_data *mpd)
 	mpd->map.m_len = 0;
 	mpd->next_page = index;
 	while (index <= end) {
-		nr_pages = pagevec_lookup_tag(&pvec, mapping, &index, tag,
-			      min(end - index, (pgoff_t)PAGEVEC_SIZE-1) + 1);
+		nr_pages = pagevec_lookup_range_tag(&pvec, mapping, &index, end,
+				tag, PAGEVEC_SIZE);
 		if (nr_pages == 0)
 			goto out;
 
@@ -2564,16 +2564,6 @@ static int mpage_prepare_extent_to_map(struct mpage_da_data *mpd)
 			struct page *page = pvec.pages[i];
 
 			/*
-			 * At this point, the page may be truncated or
-			 * invalidated (changing page->mapping to NULL), or
-			 * even swizzled back from swapper_space to tmpfs file
-			 * mapping. However, page->index will not change
-			 * because we have a reference on the page.
-			 */
-			if (page->index > end)
-				goto out;
-
-			/*
 			 * Accumulated enough dirty pages? This doesn't apply
 			 * to WB_SYNC_ALL mode. For integrity sync we have to
 			 * keep going because someone may be concurrently
-- 
2.12.3

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 18/35] f2fs: Use pagevec_lookup_range_tag()
  2017-06-01  9:32 [PATCH 00/35 v1] pagevec API cleanups Jan Kara
                   ` (16 preceding siblings ...)
  2017-06-01  9:32 ` [PATCH 17/35] ext4: " Jan Kara
@ 2017-06-01  9:32 ` Jan Kara
  2017-06-01  9:32 ` [PATCH 19/35] f2fs: Simplify page iteration loops Jan Kara
                   ` (18 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Jan Kara @ 2017-06-01  9:32 UTC (permalink / raw)
  To: linux-mm
  Cc: Hugh Dickins, David Howells, linux-afs, Ryusuke Konishi,
	linux-nilfs, Bob Peterson, cluster-devel, Jaegeuk Kim,
	linux-f2fs-devel, tytso, linux-ext4, Ilya Dryomov, Yan, Zheng,
	ceph-devel, linux-btrfs, David Sterba, Darrick J . Wong,
	linux-xfs, Nadia Yvette Chambers, Jan Kara

We want only pages from given range in f2fs_write_cache_pages(). Use
pagevec_lookup_range_tag() instead of pagevec_lookup_tag() and remove
unnecessary code.

CC: Jaegeuk Kim <jaegeuk@kernel.org>
CC: linux-f2fs-devel@lists.sourceforge.net
Signed-off-by: Jan Kara <jack@suse.cz>
---
 fs/f2fs/data.c | 9 ++-------
 1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 7c0f6bdf817d..3e6244a82ac5 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -1603,8 +1603,8 @@ static int f2fs_write_cache_pages(struct address_space *mapping,
 	while (!done && (index <= end)) {
 		int i;
 
-		nr_pages = pagevec_lookup_tag(&pvec, mapping, &index, tag,
-			      min(end - index, (pgoff_t)PAGEVEC_SIZE - 1) + 1);
+		nr_pages = pagevec_lookup_range_tag(&pvec, mapping, &index, end,
+				tag, PAGEVEC_SIZE);
 		if (nr_pages == 0)
 			break;
 
@@ -1612,11 +1612,6 @@ static int f2fs_write_cache_pages(struct address_space *mapping,
 			struct page *page = pvec.pages[i];
 			bool submitted = false;
 
-			if (page->index > end) {
-				done = 1;
-				break;
-			}
-
 			done_index = page->index;
 
 			lock_page(page);
-- 
2.12.3

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 19/35] f2fs: Simplify page iteration loops
  2017-06-01  9:32 [PATCH 00/35 v1] pagevec API cleanups Jan Kara
                   ` (17 preceding siblings ...)
  2017-06-01  9:32 ` [PATCH 18/35] f2fs: " Jan Kara
@ 2017-06-01  9:32 ` Jan Kara
  2017-06-01 13:00   ` kbuild test robot
  2017-06-01  9:32 ` [PATCH 20/35] f2fs: Use find_get_pages_tag() for looking up single page Jan Kara
                   ` (17 subsequent siblings)
  36 siblings, 1 reply; 43+ messages in thread
From: Jan Kara @ 2017-06-01  9:32 UTC (permalink / raw)
  To: linux-mm
  Cc: Hugh Dickins, David Howells, linux-afs, Ryusuke Konishi,
	linux-nilfs, Bob Peterson, cluster-devel, Jaegeuk Kim,
	linux-f2fs-devel, tytso, linux-ext4, Ilya Dryomov, Yan, Zheng,
	ceph-devel, linux-btrfs, David Sterba, Darrick J . Wong,
	linux-xfs, Nadia Yvette Chambers, Jan Kara

In several places we want to iterate over all tagged pages in a mapping.
However the code was apparently copied from places that iterate only
over a limited range and thus it checks for index <= end, optimizes the
case where we are coming close to range end which is all pointless when
end == ULONG_MAX. So just remove this dead code.

CC: Jaegeuk Kim <jaegeuk@kernel.org>
CC: linux-f2fs-devel@lists.sourceforge.net
Signed-off-by: Jan Kara <jack@suse.cz>
---
 fs/f2fs/checkpoint.c | 13 ++++-------
 fs/f2fs/node.c       | 65 +++++++++++++++++++---------------------------------
 2 files changed, 28 insertions(+), 50 deletions(-)

diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index ea9c317b5916..6da86eac758a 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -296,9 +296,10 @@ long sync_meta_pages(struct f2fs_sb_info *sbi, enum page_type type,
 						long nr_to_write)
 {
 	struct address_space *mapping = META_MAPPING(sbi);
-	pgoff_t index = 0, end = ULONG_MAX, prev = ULONG_MAX;
+	pgoff_t index = 0, prev = ULONG_MAX;
 	struct pagevec pvec;
 	long nwritten = 0;
+	int nr_pages;
 	struct writeback_control wbc = {
 		.for_reclaim = 0,
 	};
@@ -308,13 +309,9 @@ long sync_meta_pages(struct f2fs_sb_info *sbi, enum page_type type,
 
 	blk_start_plug(&plug);
 
-	while (index <= end) {
-		int i, nr_pages;
-		nr_pages = pagevec_lookup_tag(&pvec, mapping, &index,
-				PAGECACHE_TAG_DIRTY,
-				min(end - index, (pgoff_t)PAGEVEC_SIZE-1) + 1);
-		if (unlikely(nr_pages == 0))
-			break;
+	while (nr_pages = pagevec_lookup_tag(&pvec, mapping, &index,
+				PAGECACHE_TAG_DIRTY, PAGEVEC_SIZE)) {
+		int i;
 
 		for (i = 0; i < nr_pages; i++) {
 			struct page *page = pvec.pages[i];
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index 4547c5c5cd98..dd53bcd9fc46 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -1259,21 +1259,17 @@ void move_node_page(struct page *node_page, int gc_type)
 
 static struct page *last_fsync_dnode(struct f2fs_sb_info *sbi, nid_t ino)
 {
-	pgoff_t index, end;
+	pgoff_t index;
 	struct pagevec pvec;
 	struct page *last_page = NULL;
+	int nr_pages;
 
 	pagevec_init(&pvec, 0);
 	index = 0;
-	end = ULONG_MAX;
-
-	while (index <= end) {
-		int i, nr_pages;
-		nr_pages = pagevec_lookup_tag(&pvec, NODE_MAPPING(sbi), &index,
-				PAGECACHE_TAG_DIRTY,
-				min(end - index, (pgoff_t)PAGEVEC_SIZE-1) + 1);
-		if (nr_pages == 0)
-			break;
+
+	while (nr_pages = pagevec_lookup_tag(&pvec, NODE_MAPPING(sbi), &index,
+				PAGECACHE_TAG_DIRTY, PAGEVEC_SIZE)) {
+		int i;
 
 		for (i = 0; i < nr_pages; i++) {
 			struct page *page = pvec.pages[i];
@@ -1403,13 +1399,14 @@ static int f2fs_write_node_page(struct page *page,
 int fsync_node_pages(struct f2fs_sb_info *sbi, struct inode *inode,
 			struct writeback_control *wbc, bool atomic)
 {
-	pgoff_t index, end;
+	pgoff_t index;
 	pgoff_t last_idx = ULONG_MAX;
 	struct pagevec pvec;
 	int ret = 0;
 	struct page *last_page = NULL;
 	bool marked = false;
 	nid_t ino = inode->i_ino;
+	int nr_pages;
 
 	if (atomic) {
 		last_page = last_fsync_dnode(sbi, ino);
@@ -1419,15 +1416,10 @@ int fsync_node_pages(struct f2fs_sb_info *sbi, struct inode *inode,
 retry:
 	pagevec_init(&pvec, 0);
 	index = 0;
-	end = ULONG_MAX;
-
-	while (index <= end) {
-		int i, nr_pages;
-		nr_pages = pagevec_lookup_tag(&pvec, NODE_MAPPING(sbi), &index,
-				PAGECACHE_TAG_DIRTY,
-				min(end - index, (pgoff_t)PAGEVEC_SIZE-1) + 1);
-		if (nr_pages == 0)
-			break;
+
+	while (nr_pages = pagevec_lookup_tag(&pvec, NODE_MAPPING(sbi), &index,
+				PAGECACHE_TAG_DIRTY, PAGEVEC_SIZE)) {
+		int i;
 
 		for (i = 0; i < nr_pages; i++) {
 			struct page *page = pvec.pages[i];
@@ -1525,25 +1517,21 @@ int fsync_node_pages(struct f2fs_sb_info *sbi, struct inode *inode,
 
 int sync_node_pages(struct f2fs_sb_info *sbi, struct writeback_control *wbc)
 {
-	pgoff_t index, end;
+	pgoff_t index;
 	struct pagevec pvec;
 	int step = 0;
 	int nwritten = 0;
 	int ret = 0;
+	int nr_pages;
 
 	pagevec_init(&pvec, 0);
 
 next_step:
 	index = 0;
-	end = ULONG_MAX;
-
-	while (index <= end) {
-		int i, nr_pages;
-		nr_pages = pagevec_lookup_tag(&pvec, NODE_MAPPING(sbi), &index,
-				PAGECACHE_TAG_DIRTY,
-				min(end - index, (pgoff_t)PAGEVEC_SIZE-1) + 1);
-		if (nr_pages == 0)
-			break;
+
+	while (nr_pages = pagevec_lookup_tag(&pvec, NODE_MAPPING(sbi), &index,
+				PAGECACHE_TAG_DIRTY, PAGEVEC_SIZE)) {
+		int i;
 
 		for (i = 0; i < nr_pages; i++) {
 			struct page *page = pvec.pages[i];
@@ -1631,27 +1619,20 @@ int sync_node_pages(struct f2fs_sb_info *sbi, struct writeback_control *wbc)
 
 int wait_on_node_pages_writeback(struct f2fs_sb_info *sbi, nid_t ino)
 {
-	pgoff_t index = 0, end = ULONG_MAX;
+	pgoff_t index = 0;
 	struct pagevec pvec;
 	int ret2, ret = 0;
+	int nr_pages;
 
 	pagevec_init(&pvec, 0);
 
-	while (index <= end) {
-		int i, nr_pages;
-		nr_pages = pagevec_lookup_tag(&pvec, NODE_MAPPING(sbi), &index,
-				PAGECACHE_TAG_WRITEBACK,
-				min(end - index, (pgoff_t)PAGEVEC_SIZE-1) + 1);
-		if (nr_pages == 0)
-			break;
+	while (nr_pages = pagevec_lookup_tag(&pvec, NODE_MAPPING(sbi), &index,
+				PAGECACHE_TAG_WRITEBACK, PAGEVEC_SIZE)) {
+		int i;
 
 		for (i = 0; i < nr_pages; i++) {
 			struct page *page = pvec.pages[i];
 
-			/* until radix tree lookup accepts end_index */
-			if (unlikely(page->index > end))
-				continue;
-
 			if (ino && ino_of_node(page) == ino) {
 				f2fs_wait_on_page_writeback(page, NODE, true);
 				if (TestClearPageError(page))
-- 
2.12.3

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 20/35] f2fs: Use find_get_pages_tag() for looking up single page
  2017-06-01  9:32 [PATCH 00/35 v1] pagevec API cleanups Jan Kara
                   ` (18 preceding siblings ...)
  2017-06-01  9:32 ` [PATCH 19/35] f2fs: Simplify page iteration loops Jan Kara
@ 2017-06-01  9:32 ` Jan Kara
  2017-06-01  9:32 ` [PATCH 21/35] gfs2: Use pagevec_lookup_range_tag() Jan Kara
                   ` (16 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Jan Kara @ 2017-06-01  9:32 UTC (permalink / raw)
  To: linux-mm
  Cc: Hugh Dickins, David Howells, linux-afs, Ryusuke Konishi,
	linux-nilfs, Bob Peterson, cluster-devel, Jaegeuk Kim,
	linux-f2fs-devel, tytso, linux-ext4, Ilya Dryomov, Yan, Zheng,
	ceph-devel, linux-btrfs, David Sterba, Darrick J . Wong,
	linux-xfs, Nadia Yvette Chambers, Jan Kara

__get_first_dirty_index() wants to lookup only the first dirty page
after given index. There's no point in using pagevec_lookup_tag() for
that. Just use find_get_pages_tag() directly.

CC: Jaegeuk Kim <jaegeuk@kernel.org>
CC: linux-f2fs-devel@lists.sourceforge.net
Signed-off-by: Jan Kara <jack@suse.cz>
---
 fs/f2fs/file.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index 61af721329fa..52df1ef66883 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -286,18 +286,19 @@ int f2fs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
 static pgoff_t __get_first_dirty_index(struct address_space *mapping,
 						pgoff_t pgofs, int whence)
 {
-	struct pagevec pvec;
+	struct page *page;
 	int nr_pages;
 
 	if (whence != SEEK_DATA)
 		return 0;
 
 	/* find first dirty page index */
-	pagevec_init(&pvec, 0);
-	nr_pages = pagevec_lookup_tag(&pvec, mapping, &pgofs,
-					PAGECACHE_TAG_DIRTY, 1);
-	pgofs = nr_pages ? pvec.pages[0]->index : ULONG_MAX;
-	pagevec_release(&pvec);
+	nr_pages = find_get_pages_tag(mapping, &pgofs, PAGECACHE_TAG_DIRTY,
+				      1, &page);
+	if (!nr_pages)
+		return ULONG_MAX;
+	pgofs = page->index;
+	put_page(page);
 	return pgofs;
 }
 
-- 
2.12.3

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 21/35] gfs2: Use pagevec_lookup_range_tag()
  2017-06-01  9:32 [PATCH 00/35 v1] pagevec API cleanups Jan Kara
                   ` (19 preceding siblings ...)
  2017-06-01  9:32 ` [PATCH 20/35] f2fs: Use find_get_pages_tag() for looking up single page Jan Kara
@ 2017-06-01  9:32 ` Jan Kara
  2017-06-01  9:32 ` [PATCH 22/35] nilfs2: " Jan Kara
                   ` (15 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Jan Kara @ 2017-06-01  9:32 UTC (permalink / raw)
  To: linux-mm
  Cc: Hugh Dickins, David Howells, linux-afs, Ryusuke Konishi,
	linux-nilfs, Bob Peterson, cluster-devel, Jaegeuk Kim,
	linux-f2fs-devel, tytso, linux-ext4, Ilya Dryomov, Yan, Zheng,
	ceph-devel, linux-btrfs, David Sterba, Darrick J . Wong,
	linux-xfs, Nadia Yvette Chambers, Jan Kara

We want only pages from given range in gfs2_write_cache_jdata(). Use
pagevec_lookup_range_tag() instead of pagevec_lookup_tag() and remove
unnecessary code.

CC: Bob Peterson <rpeterso@redhat.com>
CC: cluster-devel@redhat.com
Signed-off-by: Jan Kara <jack@suse.cz>
---
 fs/gfs2/aops.c | 20 ++------------------
 1 file changed, 2 insertions(+), 18 deletions(-)

diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c
index ed7a2e252ad8..158ceb900ab5 100644
--- a/fs/gfs2/aops.c
+++ b/fs/gfs2/aops.c
@@ -268,22 +268,6 @@ static int gfs2_write_jdata_pagevec(struct address_space *mapping,
 	for(i = 0; i < nr_pages; i++) {
 		struct page *page = pvec->pages[i];
 
-		/*
-		 * At this point, the page may be truncated or
-		 * invalidated (changing page->mapping to NULL), or
-		 * even swizzled back from swapper_space to tmpfs file
-		 * mapping. However, page->index will not change
-		 * because we have a reference on the page.
-		 */
-		if (page->index > end) {
-			/*
-			 * can't be range_cyclic (1st pass) because
-			 * end == -1 in that case.
-			 */
-			ret = 1;
-			break;
-		}
-
 		*done_index = page->index;
 
 		lock_page(page);
@@ -401,8 +385,8 @@ static int gfs2_write_cache_jdata(struct address_space *mapping,
 		tag_pages_for_writeback(mapping, index, end);
 	done_index = index;
 	while (!done && (index <= end)) {
-		nr_pages = pagevec_lookup_tag(&pvec, mapping, &index, tag,
-			      min(end - index, (pgoff_t)PAGEVEC_SIZE-1) + 1);
+		nr_pages = pagevec_lookup_range_tag(&pvec, mapping, &index, end,
+				tag, PAGEVEC_SIZE);
 		if (nr_pages == 0)
 			break;
 
-- 
2.12.3

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 22/35] nilfs2: Use pagevec_lookup_range_tag()
  2017-06-01  9:32 [PATCH 00/35 v1] pagevec API cleanups Jan Kara
                   ` (20 preceding siblings ...)
  2017-06-01  9:32 ` [PATCH 21/35] gfs2: Use pagevec_lookup_range_tag() Jan Kara
@ 2017-06-01  9:32 ` Jan Kara
  2017-06-01  9:32 ` [PATCH 23/35] mm: Use pagevec_lookup_range_tag() in __filemap_fdatawait_range() Jan Kara
                   ` (14 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Jan Kara @ 2017-06-01  9:32 UTC (permalink / raw)
  To: linux-mm
  Cc: Hugh Dickins, David Howells, linux-afs, Ryusuke Konishi,
	linux-nilfs, Bob Peterson, cluster-devel, Jaegeuk Kim,
	linux-f2fs-devel, tytso, linux-ext4, Ilya Dryomov, Yan, Zheng,
	ceph-devel, linux-btrfs, David Sterba, Darrick J . Wong,
	linux-xfs, Nadia Yvette Chambers, Jan Kara

We want only pages from given range in
nilfs_lookup_dirty_data_buffers(). Use pagevec_lookup_range_tag()
instead of pagevec_lookup_tag() and remove unnecessary code.

CC: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
CC: linux-nilfs@vger.kernel.org
Signed-off-by: Jan Kara <jack@suse.cz>
---
 fs/nilfs2/segment.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c
index febed1217b3f..fd9eeca5f784 100644
--- a/fs/nilfs2/segment.c
+++ b/fs/nilfs2/segment.c
@@ -711,18 +711,14 @@ static size_t nilfs_lookup_dirty_data_buffers(struct inode *inode,
 	pagevec_init(&pvec, 0);
  repeat:
 	if (unlikely(index > last) ||
-	    !pagevec_lookup_tag(&pvec, mapping, &index, PAGECACHE_TAG_DIRTY,
-				min_t(pgoff_t, last - index,
-				      PAGEVEC_SIZE - 1) + 1))
+	    !pagevec_lookup_range_tag(&pvec, mapping, &index, last,
+				PAGECACHE_TAG_DIRTY, PAGEVEC_SIZE))
 		return ndirties;
 
 	for (i = 0; i < pagevec_count(&pvec); i++) {
 		struct buffer_head *bh, *head;
 		struct page *page = pvec.pages[i];
 
-		if (unlikely(page->index > last))
-			break;
-
 		lock_page(page);
 		if (!page_has_buffers(page))
 			create_empty_buffers(page, i_blocksize(inode), 0);
-- 
2.12.3

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 23/35] mm: Use pagevec_lookup_range_tag() in __filemap_fdatawait_range()
  2017-06-01  9:32 [PATCH 00/35 v1] pagevec API cleanups Jan Kara
                   ` (21 preceding siblings ...)
  2017-06-01  9:32 ` [PATCH 22/35] nilfs2: " Jan Kara
@ 2017-06-01  9:32 ` Jan Kara
  2017-06-01  9:32 ` [PATCH 24/35] mm: Use pagevec_lookup_range_tag() in write_cache_pages() Jan Kara
                   ` (13 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Jan Kara @ 2017-06-01  9:32 UTC (permalink / raw)
  To: linux-mm
  Cc: Hugh Dickins, David Howells, linux-afs, Ryusuke Konishi,
	linux-nilfs, Bob Peterson, cluster-devel, Jaegeuk Kim,
	linux-f2fs-devel, tytso, linux-ext4, Ilya Dryomov, Yan, Zheng,
	ceph-devel, linux-btrfs, David Sterba, Darrick J . Wong,
	linux-xfs, Nadia Yvette Chambers, Jan Kara

Use pagevec_lookup_range_tag() in __filemap_fdatawait_range() as it is
interested only in pages from given range. Remove unnecessary code
resulting from this.

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

diff --git a/mm/filemap.c b/mm/filemap.c
index 56af68f6a375..8039b6bb9c27 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -390,18 +390,13 @@ static int __filemap_fdatawait_range(struct address_space *mapping,
 
 	pagevec_init(&pvec, 0);
 	while ((index <= end) &&
-			(nr_pages = pagevec_lookup_tag(&pvec, mapping, &index,
-			PAGECACHE_TAG_WRITEBACK,
-			min(end - index, (pgoff_t)PAGEVEC_SIZE-1) + 1)) != 0) {
+			(nr_pages = pagevec_lookup_range_tag(&pvec, mapping,
+			&index, end, PAGECACHE_TAG_WRITEBACK, PAGEVEC_SIZE))) {
 		unsigned i;
 
 		for (i = 0; i < nr_pages; i++) {
 			struct page *page = pvec.pages[i];
 
-			/* until radix tree lookup accepts end_index */
-			if (page->index > end)
-				continue;
-
 			wait_on_page_writeback(page);
 			if (TestClearPageError(page))
 				ret = -EIO;
-- 
2.12.3

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 24/35] mm: Use pagevec_lookup_range_tag() in write_cache_pages()
  2017-06-01  9:32 [PATCH 00/35 v1] pagevec API cleanups Jan Kara
                   ` (22 preceding siblings ...)
  2017-06-01  9:32 ` [PATCH 23/35] mm: Use pagevec_lookup_range_tag() in __filemap_fdatawait_range() Jan Kara
@ 2017-06-01  9:32 ` Jan Kara
  2017-06-01  9:32 ` [PATCH 25/35] mm: Remove nr_pages argument from pagevec_lookup_{,range}_tag() Jan Kara
                   ` (12 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Jan Kara @ 2017-06-01  9:32 UTC (permalink / raw)
  To: linux-mm
  Cc: Hugh Dickins, David Howells, linux-afs, Ryusuke Konishi,
	linux-nilfs, Bob Peterson, cluster-devel, Jaegeuk Kim,
	linux-f2fs-devel, tytso, linux-ext4, Ilya Dryomov, Yan, Zheng,
	ceph-devel, linux-btrfs, David Sterba, Darrick J . Wong,
	linux-xfs, Nadia Yvette Chambers, Jan Kara

Use pagevec_lookup_range_tag() in write_cache_pages() as it is
interested only in pages from given range. Remove unnecessary code
resulting from this.

Signed-off-by: Jan Kara <jack@suse.cz>
---
 mm/page-writeback.c | 20 ++------------------
 1 file changed, 2 insertions(+), 18 deletions(-)

diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index 143c1c25d680..c77c387465ec 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -2194,30 +2194,14 @@ int write_cache_pages(struct address_space *mapping,
 	while (!done && (index <= end)) {
 		int i;
 
-		nr_pages = pagevec_lookup_tag(&pvec, mapping, &index, tag,
-			      min(end - index, (pgoff_t)PAGEVEC_SIZE-1) + 1);
+		nr_pages = pagevec_lookup_range_tag(&pvec, mapping, &index, end,
+				tag, PAGEVEC_SIZE);
 		if (nr_pages == 0)
 			break;
 
 		for (i = 0; i < nr_pages; i++) {
 			struct page *page = pvec.pages[i];
 
-			/*
-			 * At this point, the page may be truncated or
-			 * invalidated (changing page->mapping to NULL), or
-			 * even swizzled back from swapper_space to tmpfs file
-			 * mapping. However, page->index will not change
-			 * because we have a reference on the page.
-			 */
-			if (page->index > end) {
-				/*
-				 * can't be range_cyclic (1st pass) because
-				 * end == -1 in that case.
-				 */
-				done = 1;
-				break;
-			}
-
 			done_index = page->index;
 
 			lock_page(page);
-- 
2.12.3

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 25/35] mm: Remove nr_pages argument from pagevec_lookup_{,range}_tag()
  2017-06-01  9:32 [PATCH 00/35 v1] pagevec API cleanups Jan Kara
                   ` (23 preceding siblings ...)
  2017-06-01  9:32 ` [PATCH 24/35] mm: Use pagevec_lookup_range_tag() in write_cache_pages() Jan Kara
@ 2017-06-01  9:32 ` Jan Kara
  2017-06-01  9:32 ` [PATCH 26/35] afs: Use find_get_pages_range_tag() Jan Kara
                   ` (11 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Jan Kara @ 2017-06-01  9:32 UTC (permalink / raw)
  To: linux-mm
  Cc: Hugh Dickins, David Howells, linux-afs, Ryusuke Konishi,
	linux-nilfs, Bob Peterson, cluster-devel, Jaegeuk Kim,
	linux-f2fs-devel, tytso, linux-ext4, Ilya Dryomov, Yan, Zheng,
	ceph-devel, linux-btrfs, David Sterba, Darrick J . Wong,
	linux-xfs, Nadia Yvette Chambers, Jan Kara

All users of pagevec_lookup() and pagevec_lookup_range() now pass
PAGEVEC_SIZE as a desired number of pages. Just drop the argument.

Signed-off-by: Jan Kara <jack@suse.cz>
---
 fs/btrfs/extent_io.c    | 6 +++---
 fs/ceph/addr.c          | 3 +--
 fs/ext4/inode.c         | 2 +-
 fs/f2fs/checkpoint.c    | 2 +-
 fs/f2fs/data.c          | 2 +-
 fs/f2fs/node.c          | 8 ++++----
 fs/gfs2/aops.c          | 2 +-
 fs/nilfs2/btree.c       | 4 ++--
 fs/nilfs2/page.c        | 7 +++----
 fs/nilfs2/segment.c     | 6 +++---
 include/linux/pagevec.h | 8 +++-----
 mm/filemap.c            | 2 +-
 mm/page-writeback.c     | 2 +-
 mm/swap.c               | 4 ++--
 14 files changed, 27 insertions(+), 31 deletions(-)

diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index 6287eaba30ac..53d742a5a99b 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -3838,7 +3838,7 @@ int btree_write_cache_pages(struct address_space *mapping,
 		tag_pages_for_writeback(mapping, index, end);
 	while (!done && !nr_to_write_done && (index <= end) &&
 	       (nr_pages = pagevec_lookup_range_tag(&pvec, mapping, &index, end,
-			tag, PAGEVEC_SIZE))) {
+			tag))) {
 		unsigned i;
 
 		scanned = 1;
@@ -3979,8 +3979,8 @@ static int extent_write_cache_pages(struct address_space *mapping,
 		tag_pages_for_writeback(mapping, index, end);
 	done_index = index;
 	while (!done && !nr_to_write_done && (index <= end) &&
-	       (nr_pages = pagevec_lookup_range_tag(&pvec, mapping, &index, end,
-			tag, PAGEVEC_SIZE))) {
+			(nr_pages = pagevec_lookup_range_tag(&pvec, mapping,
+						&index, end, tag))) {
 		unsigned i;
 
 		scanned = 1;
diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c
index 0b7e56ae3b8c..a0d5c46fc9bf 100644
--- a/fs/ceph/addr.c
+++ b/fs/ceph/addr.c
@@ -848,8 +848,7 @@ static int ceph_writepages_start(struct address_space *mapping,
 get_more_pages:
 		first = -1;
 		pvec_pages = pagevec_lookup_range_tag(&pvec, mapping, &index,
-						end, PAGECACHE_TAG_DIRTY,
-						PAGEVEC_SIZE);
+						end, PAGECACHE_TAG_DIRTY);
 		dout("pagevec_lookup_range_tag got %d\n", pvec_pages);
 		if (!pvec_pages && !locked_pages)
 			break;
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 050fba2d12c2..d1896f14d72f 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -2556,7 +2556,7 @@ static int mpage_prepare_extent_to_map(struct mpage_da_data *mpd)
 	mpd->next_page = index;
 	while (index <= end) {
 		nr_pages = pagevec_lookup_range_tag(&pvec, mapping, &index, end,
-				tag, PAGEVEC_SIZE);
+				tag);
 		if (nr_pages == 0)
 			goto out;
 
diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index 6da86eac758a..ad5bc5340ba2 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -310,7 +310,7 @@ long sync_meta_pages(struct f2fs_sb_info *sbi, enum page_type type,
 	blk_start_plug(&plug);
 
 	while (nr_pages = pagevec_lookup_tag(&pvec, mapping, &index,
-				PAGECACHE_TAG_DIRTY, PAGEVEC_SIZE)) {
+				PAGECACHE_TAG_DIRTY)) {
 		int i;
 
 		for (i = 0; i < nr_pages; i++) {
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 3e6244a82ac5..afca42392fbd 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -1604,7 +1604,7 @@ static int f2fs_write_cache_pages(struct address_space *mapping,
 		int i;
 
 		nr_pages = pagevec_lookup_range_tag(&pvec, mapping, &index, end,
-				tag, PAGEVEC_SIZE);
+				tag);
 		if (nr_pages == 0)
 			break;
 
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index dd53bcd9fc46..00cae42c778a 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -1268,7 +1268,7 @@ static struct page *last_fsync_dnode(struct f2fs_sb_info *sbi, nid_t ino)
 	index = 0;
 
 	while (nr_pages = pagevec_lookup_tag(&pvec, NODE_MAPPING(sbi), &index,
-				PAGECACHE_TAG_DIRTY, PAGEVEC_SIZE)) {
+				PAGECACHE_TAG_DIRTY)) {
 		int i;
 
 		for (i = 0; i < nr_pages; i++) {
@@ -1418,7 +1418,7 @@ int fsync_node_pages(struct f2fs_sb_info *sbi, struct inode *inode,
 	index = 0;
 
 	while (nr_pages = pagevec_lookup_tag(&pvec, NODE_MAPPING(sbi), &index,
-				PAGECACHE_TAG_DIRTY, PAGEVEC_SIZE)) {
+				PAGECACHE_TAG_DIRTY)) {
 		int i;
 
 		for (i = 0; i < nr_pages; i++) {
@@ -1530,7 +1530,7 @@ int sync_node_pages(struct f2fs_sb_info *sbi, struct writeback_control *wbc)
 	index = 0;
 
 	while (nr_pages = pagevec_lookup_tag(&pvec, NODE_MAPPING(sbi), &index,
-				PAGECACHE_TAG_DIRTY, PAGEVEC_SIZE)) {
+				PAGECACHE_TAG_DIRTY)) {
 		int i;
 
 		for (i = 0; i < nr_pages; i++) {
@@ -1627,7 +1627,7 @@ int wait_on_node_pages_writeback(struct f2fs_sb_info *sbi, nid_t ino)
 	pagevec_init(&pvec, 0);
 
 	while (nr_pages = pagevec_lookup_tag(&pvec, NODE_MAPPING(sbi), &index,
-				PAGECACHE_TAG_WRITEBACK, PAGEVEC_SIZE)) {
+				PAGECACHE_TAG_WRITEBACK)) {
 		int i;
 
 		for (i = 0; i < nr_pages; i++) {
diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c
index 158ceb900ab5..903a1c9f60a5 100644
--- a/fs/gfs2/aops.c
+++ b/fs/gfs2/aops.c
@@ -386,7 +386,7 @@ static int gfs2_write_cache_jdata(struct address_space *mapping,
 	done_index = index;
 	while (!done && (index <= end)) {
 		nr_pages = pagevec_lookup_range_tag(&pvec, mapping, &index, end,
-				tag, PAGEVEC_SIZE);
+				tag);
 		if (nr_pages == 0)
 			break;
 
diff --git a/fs/nilfs2/btree.c b/fs/nilfs2/btree.c
index 06ffa135dfa6..35989c7bb065 100644
--- a/fs/nilfs2/btree.c
+++ b/fs/nilfs2/btree.c
@@ -2158,8 +2158,8 @@ static void nilfs_btree_lookup_dirty_buffers(struct nilfs_bmap *btree,
 
 	pagevec_init(&pvec, 0);
 
-	while (pagevec_lookup_tag(&pvec, btcache, &index, PAGECACHE_TAG_DIRTY,
-				  PAGEVEC_SIZE)) {
+	while (pagevec_lookup_tag(&pvec, btcache, &index,
+					PAGECACHE_TAG_DIRTY)) {
 		for (i = 0; i < pagevec_count(&pvec); i++) {
 			bh = head = page_buffers(pvec.pages[i]);
 			do {
diff --git a/fs/nilfs2/page.c b/fs/nilfs2/page.c
index 8616c46d33da..1c16726915c1 100644
--- a/fs/nilfs2/page.c
+++ b/fs/nilfs2/page.c
@@ -257,8 +257,7 @@ int nilfs_copy_dirty_pages(struct address_space *dmap,
 
 	pagevec_init(&pvec, 0);
 repeat:
-	if (!pagevec_lookup_tag(&pvec, smap, &index, PAGECACHE_TAG_DIRTY,
-				PAGEVEC_SIZE))
+	if (!pagevec_lookup_tag(&pvec, smap, &index, PAGECACHE_TAG_DIRTY))
 		return 0;
 
 	for (i = 0; i < pagevec_count(&pvec); i++) {
@@ -376,8 +375,8 @@ void nilfs_clear_dirty_pages(struct address_space *mapping, bool silent)
 
 	pagevec_init(&pvec, 0);
 
-	while (pagevec_lookup_tag(&pvec, mapping, &index, PAGECACHE_TAG_DIRTY,
-				  PAGEVEC_SIZE)) {
+	while (pagevec_lookup_tag(&pvec, mapping, &index,
+					PAGECACHE_TAG_DIRTY)) {
 		for (i = 0; i < pagevec_count(&pvec); i++) {
 			struct page *page = pvec.pages[i];
 
diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c
index fd9eeca5f784..c123f1590e41 100644
--- a/fs/nilfs2/segment.c
+++ b/fs/nilfs2/segment.c
@@ -712,7 +712,7 @@ static size_t nilfs_lookup_dirty_data_buffers(struct inode *inode,
  repeat:
 	if (unlikely(index > last) ||
 	    !pagevec_lookup_range_tag(&pvec, mapping, &index, last,
-				PAGECACHE_TAG_DIRTY, PAGEVEC_SIZE))
+				PAGECACHE_TAG_DIRTY))
 		return ndirties;
 
 	for (i = 0; i < pagevec_count(&pvec); i++) {
@@ -755,8 +755,8 @@ static void nilfs_lookup_dirty_node_buffers(struct inode *inode,
 
 	pagevec_init(&pvec, 0);
 
-	while (pagevec_lookup_tag(&pvec, mapping, &index, PAGECACHE_TAG_DIRTY,
-				  PAGEVEC_SIZE)) {
+	while (pagevec_lookup_tag(&pvec, mapping, &index,
+					PAGECACHE_TAG_DIRTY)) {
 		for (i = 0; i < pagevec_count(&pvec); i++) {
 			bh = head = page_buffers(pvec.pages[i]);
 			do {
diff --git a/include/linux/pagevec.h b/include/linux/pagevec.h
index 371edacc10d5..f3f2b9690764 100644
--- a/include/linux/pagevec.h
+++ b/include/linux/pagevec.h
@@ -39,13 +39,11 @@ static inline unsigned pagevec_lookup(struct pagevec *pvec,
 
 unsigned pagevec_lookup_range_tag(struct pagevec *pvec,
 		struct address_space *mapping, pgoff_t *index, pgoff_t end,
-		int tag, unsigned nr_pages);
+		int tag);
 static inline unsigned pagevec_lookup_tag(struct pagevec *pvec,
-		struct address_space *mapping, pgoff_t *index, int tag,
-		unsigned nr_pages)
+		struct address_space *mapping, pgoff_t *index, int tag)
 {
-	return pagevec_lookup_range_tag(pvec, mapping, index, (pgoff_t)-1, tag,
-					nr_pages);
+	return pagevec_lookup_range_tag(pvec, mapping, index, (pgoff_t)-1, tag);
 }
 
 static inline void pagevec_init(struct pagevec *pvec, int cold)
diff --git a/mm/filemap.c b/mm/filemap.c
index 8039b6bb9c27..910f2e39fef2 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -391,7 +391,7 @@ static int __filemap_fdatawait_range(struct address_space *mapping,
 	pagevec_init(&pvec, 0);
 	while ((index <= end) &&
 			(nr_pages = pagevec_lookup_range_tag(&pvec, mapping,
-			&index, end, PAGECACHE_TAG_WRITEBACK, PAGEVEC_SIZE))) {
+			&index, end, PAGECACHE_TAG_WRITEBACK))) {
 		unsigned i;
 
 		for (i = 0; i < nr_pages; i++) {
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index c77c387465ec..6fd235139d8e 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -2195,7 +2195,7 @@ int write_cache_pages(struct address_space *mapping,
 		int i;
 
 		nr_pages = pagevec_lookup_range_tag(&pvec, mapping, &index, end,
-				tag, PAGEVEC_SIZE);
+				tag);
 		if (nr_pages == 0)
 			break;
 
diff --git a/mm/swap.c b/mm/swap.c
index 4714d07965c1..dc63970f79b9 100644
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -971,10 +971,10 @@ EXPORT_SYMBOL(pagevec_lookup_range);
 
 unsigned pagevec_lookup_range_tag(struct pagevec *pvec,
 		struct address_space *mapping, pgoff_t *index, pgoff_t end,
-		int tag, unsigned nr_pages)
+		int tag)
 {
 	pvec->nr = find_get_pages_range_tag(mapping, index, end, tag,
-					nr_pages, pvec->pages);
+					PAGEVEC_SIZE, pvec->pages);
 	return pagevec_count(pvec);
 }
 EXPORT_SYMBOL(pagevec_lookup_range_tag);
-- 
2.12.3

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 26/35] afs: Use find_get_pages_range_tag()
  2017-06-01  9:32 [PATCH 00/35 v1] pagevec API cleanups Jan Kara
                   ` (24 preceding siblings ...)
  2017-06-01  9:32 ` [PATCH 25/35] mm: Remove nr_pages argument from pagevec_lookup_{,range}_tag() Jan Kara
@ 2017-06-01  9:32 ` Jan Kara
  2017-06-01  9:32 ` [PATCH 27/35] shmem: Use pagevec_lookup() in shmem_unlock_mapping() Jan Kara
                   ` (10 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Jan Kara @ 2017-06-01  9:32 UTC (permalink / raw)
  To: linux-mm
  Cc: Hugh Dickins, David Howells, linux-afs, Ryusuke Konishi,
	linux-nilfs, Bob Peterson, cluster-devel, Jaegeuk Kim,
	linux-f2fs-devel, tytso, linux-ext4, Ilya Dryomov, Yan, Zheng,
	ceph-devel, linux-btrfs, David Sterba, Darrick J . Wong,
	linux-xfs, Nadia Yvette Chambers, Jan Kara

Use find_get_pages_range_tag() in afs_writepages_region() as we are
interested only in pages from given range. Remove unnecessary code after
this conversion.

CC: David Howells <dhowells@redhat.com>
CC: linux-afs@lists.infradead.org
Signed-off-by: Jan Kara <jack@suse.cz>
---
 fs/afs/write.c | 11 ++---------
 1 file changed, 2 insertions(+), 9 deletions(-)

diff --git a/fs/afs/write.c b/fs/afs/write.c
index 2d2fccd5044b..630f2a42fae7 100644
--- a/fs/afs/write.c
+++ b/fs/afs/write.c
@@ -497,20 +497,13 @@ static int afs_writepages_region(struct address_space *mapping,
 	_enter(",,%lx,%lx,", index, end);
 
 	do {
-		n = find_get_pages_tag(mapping, &index, PAGECACHE_TAG_DIRTY,
-				       1, &page);
+		n = find_get_pages_range_tag(mapping, &index, end,
+					PAGECACHE_TAG_DIRTY, 1, &page);
 		if (!n)
 			break;
 
 		_debug("wback %lx", page->index);
 
-		if (page->index > end) {
-			*_next = index;
-			put_page(page);
-			_leave(" = 0 [%lx]", *_next);
-			return 0;
-		}
-
 		/* at this point we hold neither mapping->tree_lock nor lock on
 		 * the page itself: the page may be truncated or invalidated
 		 * (changing page->mapping to NULL), or even swizzled back from
-- 
2.12.3

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 27/35] shmem: Use pagevec_lookup() in shmem_unlock_mapping()
  2017-06-01  9:32 [PATCH 00/35 v1] pagevec API cleanups Jan Kara
                   ` (25 preceding siblings ...)
  2017-06-01  9:32 ` [PATCH 26/35] afs: Use find_get_pages_range_tag() Jan Kara
@ 2017-06-01  9:32 ` Jan Kara
  2017-06-01  9:32 ` [PATCH 28/35] shmem: Use pagevec_lookup_entries() Jan Kara
                   ` (9 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Jan Kara @ 2017-06-01  9:32 UTC (permalink / raw)
  To: linux-mm
  Cc: Hugh Dickins, David Howells, linux-afs, Ryusuke Konishi,
	linux-nilfs, Bob Peterson, cluster-devel, Jaegeuk Kim,
	linux-f2fs-devel, tytso, linux-ext4, Ilya Dryomov, Yan, Zheng,
	ceph-devel, linux-btrfs, David Sterba, Darrick J . Wong,
	linux-xfs, Nadia Yvette Chambers, Jan Kara

The comment about find_get_pages() returning if it finds a row of swap
entries seems to be stale. Use pagevec_lookup() in
shmem_unlock_mapping() to simplify the code.

CC: Hugh Dickins <hughd@google.com>
Signed-off-by: Jan Kara <jack@suse.cz>
---
 mm/shmem.c | 14 ++------------
 1 file changed, 2 insertions(+), 12 deletions(-)

diff --git a/mm/shmem.c b/mm/shmem.c
index e67d6ba4e98e..a614a9cfb58c 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -729,24 +729,14 @@ unsigned long shmem_swap_usage(struct vm_area_struct *vma)
 void shmem_unlock_mapping(struct address_space *mapping)
 {
 	struct pagevec pvec;
-	pgoff_t indices[PAGEVEC_SIZE];
 	pgoff_t index = 0;
 
 	pagevec_init(&pvec, 0);
 	/*
 	 * Minor point, but we might as well stop if someone else SHM_LOCKs it.
 	 */
-	while (!mapping_unevictable(mapping)) {
-		/*
-		 * Avoid pagevec_lookup(): find_get_pages() returns 0 as if it
-		 * has finished, if it hits a row of PAGEVEC_SIZE swap entries.
-		 */
-		pvec.nr = find_get_entries(mapping, index,
-					   PAGEVEC_SIZE, pvec.pages, indices);
-		if (!pvec.nr)
-			break;
-		index = indices[pvec.nr - 1] + 1;
-		pagevec_remove_exceptionals(&pvec);
+	while (!mapping_unevictable(mapping) &&
+			pagevec_lookup(&pvec, mapping, &index)) {
 		check_move_unevictable_pages(pvec.pages, pvec.nr);
 		pagevec_release(&pvec);
 		cond_resched();
-- 
2.12.3

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 28/35] shmem: Use pagevec_lookup_entries()
  2017-06-01  9:32 [PATCH 00/35 v1] pagevec API cleanups Jan Kara
                   ` (26 preceding siblings ...)
  2017-06-01  9:32 ` [PATCH 27/35] shmem: Use pagevec_lookup() in shmem_unlock_mapping() Jan Kara
@ 2017-06-01  9:32 ` Jan Kara
  2017-06-01  9:32 ` [PATCH 29/35] mm: Make pagevec_lookup_entries() update index Jan Kara
                   ` (8 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Jan Kara @ 2017-06-01  9:32 UTC (permalink / raw)
  To: linux-mm
  Cc: Hugh Dickins, David Howells, linux-afs, Ryusuke Konishi,
	linux-nilfs, Bob Peterson, cluster-devel, Jaegeuk Kim,
	linux-f2fs-devel, tytso, linux-ext4, Ilya Dryomov, Yan, Zheng,
	ceph-devel, linux-btrfs, David Sterba, Darrick J . Wong,
	linux-xfs, Nadia Yvette Chambers, Jan Kara

Currently we use find_get_entries() shmem which just opencode what
pagevec_lookup_entries() does. Use pagevec_lookup_entries() instead
except for one case which plays tricks with number of pages looked up
and it won't fit in how we will make pagevec_lookup_entries() work.

CC: Hugh Dickins <hughd@google.com>
Signed-off-by: Jan Kara <jack@suse.cz>
---
 mm/shmem.c | 12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/mm/shmem.c b/mm/shmem.c
index a614a9cfb58c..8a6fddec27a1 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -768,10 +768,9 @@ static void shmem_undo_range(struct inode *inode, loff_t lstart, loff_t lend,
 	pagevec_init(&pvec, 0);
 	index = start;
 	while (index < end) {
-		pvec.nr = find_get_entries(mapping, index,
-			min(end - index, (pgoff_t)PAGEVEC_SIZE),
-			pvec.pages, indices);
-		if (!pvec.nr)
+		if (!pagevec_lookup_entries(&pvec, mapping, index,
+				min(end - index, (pgoff_t)PAGEVEC_SIZE),
+				indices))
 			break;
 		for (i = 0; i < pagevec_count(&pvec); i++) {
 			struct page *page = pvec.pages[i];
@@ -859,10 +858,9 @@ static void shmem_undo_range(struct inode *inode, loff_t lstart, loff_t lend,
 	while (index < end) {
 		cond_resched();
 
-		pvec.nr = find_get_entries(mapping, index,
+		if (!pagevec_lookup_entries(&pvec, mapping, index,
 				min(end - index, (pgoff_t)PAGEVEC_SIZE),
-				pvec.pages, indices);
-		if (!pvec.nr) {
+				indices)) {
 			/* If all gone or hole-punch or unfalloc, we're done */
 			if (index == start || end != -1)
 				break;
-- 
2.12.3

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 29/35] mm: Make pagevec_lookup_entries() update index
  2017-06-01  9:32 [PATCH 00/35 v1] pagevec API cleanups Jan Kara
                   ` (27 preceding siblings ...)
  2017-06-01  9:32 ` [PATCH 28/35] shmem: Use pagevec_lookup_entries() Jan Kara
@ 2017-06-01  9:32 ` Jan Kara
  2017-06-01  9:32 ` [PATCH 30/35] mm: Implement find_get_entries_range() Jan Kara
                   ` (7 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Jan Kara @ 2017-06-01  9:32 UTC (permalink / raw)
  To: linux-mm
  Cc: Hugh Dickins, David Howells, linux-afs, Ryusuke Konishi,
	linux-nilfs, Bob Peterson, cluster-devel, Jaegeuk Kim,
	linux-f2fs-devel, tytso, linux-ext4, Ilya Dryomov, Yan, Zheng,
	ceph-devel, linux-btrfs, David Sterba, Darrick J . Wong,
	linux-xfs, Nadia Yvette Chambers, Jan Kara

Make pagevec_lookup_entries() (and underlying find_get_entries()) update
index to the next page where iteration should continue. This is mostly
for consistency with pagevec_lookup() and future
pagevec_lookup_entries_range().

Signed-off-by: Jan Kara <jack@suse.cz>
---
 include/linux/pagemap.h |  2 +-
 include/linux/pagevec.h |  2 +-
 mm/filemap.c            | 11 ++++++---
 mm/shmem.c              | 57 +++++++++++++++++++++++--------------------
 mm/swap.c               |  4 +--
 mm/truncate.c           | 65 +++++++++++++++++++++++--------------------------
 6 files changed, 72 insertions(+), 69 deletions(-)

diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
index a2d3534a514f..283d191c18be 100644
--- a/include/linux/pagemap.h
+++ b/include/linux/pagemap.h
@@ -333,7 +333,7 @@ static inline struct page *grab_cache_page_nowait(struct address_space *mapping,
 
 struct page *find_get_entry(struct address_space *mapping, pgoff_t offset);
 struct page *find_lock_entry(struct address_space *mapping, pgoff_t offset);
-unsigned find_get_entries(struct address_space *mapping, pgoff_t start,
+unsigned find_get_entries(struct address_space *mapping, pgoff_t *start,
 			  unsigned int nr_entries, struct page **entries,
 			  pgoff_t *indices);
 unsigned find_get_pages_range(struct address_space *mapping, pgoff_t *start,
diff --git a/include/linux/pagevec.h b/include/linux/pagevec.h
index f3f2b9690764..3798c142338d 100644
--- a/include/linux/pagevec.h
+++ b/include/linux/pagevec.h
@@ -24,7 +24,7 @@ void __pagevec_release(struct pagevec *pvec);
 void __pagevec_lru_add(struct pagevec *pvec);
 unsigned pagevec_lookup_entries(struct pagevec *pvec,
 				struct address_space *mapping,
-				pgoff_t start, unsigned nr_entries,
+				pgoff_t *start, unsigned nr_entries,
 				pgoff_t *indices);
 void pagevec_remove_exceptionals(struct pagevec *pvec);
 unsigned pagevec_lookup_range(struct pagevec *pvec,
diff --git a/mm/filemap.c b/mm/filemap.c
index 910f2e39fef2..de12b7355821 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -1373,11 +1373,11 @@ EXPORT_SYMBOL(pagecache_get_page);
  * Any shadow entries of evicted pages, or swap entries from
  * shmem/tmpfs, are included in the returned array.
  *
- * find_get_entries() returns the number of pages and shadow entries
- * which were found.
+ * find_get_entries() returns the number of pages and shadow entries which were
+ * found. It also updates @start to index the next page for the traversal.
  */
 unsigned find_get_entries(struct address_space *mapping,
-			  pgoff_t start, unsigned int nr_entries,
+			  pgoff_t *start, unsigned int nr_entries,
 			  struct page **entries, pgoff_t *indices)
 {
 	void **slot;
@@ -1388,7 +1388,7 @@ unsigned find_get_entries(struct address_space *mapping,
 		return 0;
 
 	rcu_read_lock();
-	radix_tree_for_each_slot(slot, &mapping->page_tree, &iter, start) {
+	radix_tree_for_each_slot(slot, &mapping->page_tree, &iter, *start) {
 		struct page *head, *page;
 repeat:
 		page = radix_tree_deref_slot(slot);
@@ -1429,6 +1429,9 @@ unsigned find_get_entries(struct address_space *mapping,
 			break;
 	}
 	rcu_read_unlock();
+
+	if (ret)
+		*start = indices[ret - 1] + 1;
 	return ret;
 }
 
diff --git a/mm/shmem.c b/mm/shmem.c
index 8a6fddec27a1..f9c4afbdd70c 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -768,26 +768,25 @@ static void shmem_undo_range(struct inode *inode, loff_t lstart, loff_t lend,
 	pagevec_init(&pvec, 0);
 	index = start;
 	while (index < end) {
-		if (!pagevec_lookup_entries(&pvec, mapping, index,
+		if (!pagevec_lookup_entries(&pvec, mapping, &index,
 				min(end - index, (pgoff_t)PAGEVEC_SIZE),
 				indices))
 			break;
 		for (i = 0; i < pagevec_count(&pvec); i++) {
 			struct page *page = pvec.pages[i];
 
-			index = indices[i];
-			if (index >= end)
+			if (indices[i] >= end)
 				break;
 
 			if (radix_tree_exceptional_entry(page)) {
 				if (unfalloc)
 					continue;
 				nr_swaps_freed += !shmem_free_swap(mapping,
-								index, page);
+							indices[i], page);
 				continue;
 			}
 
-			VM_BUG_ON_PAGE(page_to_pgoff(page) != index, page);
+			VM_BUG_ON_PAGE(page_to_pgoff(page) != indices[i], page);
 
 			if (!trylock_page(page))
 				continue;
@@ -798,7 +797,8 @@ static void shmem_undo_range(struct inode *inode, loff_t lstart, loff_t lend,
 				unlock_page(page);
 				continue;
 			} else if (PageTransHuge(page)) {
-				if (index == round_down(end, HPAGE_PMD_NR)) {
+				if (indices[i] ==
+						round_down(end, HPAGE_PMD_NR)) {
 					/*
 					 * Range ends in the middle of THP:
 					 * zero out the page
@@ -807,7 +807,8 @@ static void shmem_undo_range(struct inode *inode, loff_t lstart, loff_t lend,
 					unlock_page(page);
 					continue;
 				}
-				index += HPAGE_PMD_NR - 1;
+				if (indices[i] + HPAGE_PMD_NR > index)
+					index = indices[i] + HPAGE_PMD_NR;
 				i += HPAGE_PMD_NR - 1;
 			}
 
@@ -823,7 +824,6 @@ static void shmem_undo_range(struct inode *inode, loff_t lstart, loff_t lend,
 		pagevec_remove_exceptionals(&pvec);
 		pagevec_release(&pvec);
 		cond_resched();
-		index++;
 	}
 
 	if (partial_start) {
@@ -856,13 +856,15 @@ static void shmem_undo_range(struct inode *inode, loff_t lstart, loff_t lend,
 
 	index = start;
 	while (index < end) {
+		pgoff_t lookup_start = index;
+
 		cond_resched();
 
-		if (!pagevec_lookup_entries(&pvec, mapping, index,
+		if (!pagevec_lookup_entries(&pvec, mapping, &index,
 				min(end - index, (pgoff_t)PAGEVEC_SIZE),
 				indices)) {
 			/* If all gone or hole-punch or unfalloc, we're done */
-			if (index == start || end != -1)
+			if (lookup_start == start || end != -1)
 				break;
 			/* But if truncating, restart to make sure all gone */
 			index = start;
@@ -871,16 +873,16 @@ static void shmem_undo_range(struct inode *inode, loff_t lstart, loff_t lend,
 		for (i = 0; i < pagevec_count(&pvec); i++) {
 			struct page *page = pvec.pages[i];
 
-			index = indices[i];
-			if (index >= end)
+			if (indices[i] >= end)
 				break;
 
 			if (radix_tree_exceptional_entry(page)) {
 				if (unfalloc)
 					continue;
-				if (shmem_free_swap(mapping, index, page)) {
+				if (shmem_free_swap(mapping, indices[i],
+						    page)) {
 					/* Swap was replaced by page: retry */
-					index--;
+					index = indices[i];
 					break;
 				}
 				nr_swaps_freed++;
@@ -898,11 +900,12 @@ static void shmem_undo_range(struct inode *inode, loff_t lstart, loff_t lend,
 				 * of THP: don't need to look on these pages
 				 * again on !pvec.nr restart.
 				 */
-				if (index != round_down(end, HPAGE_PMD_NR))
+				if (indices[i] != round_down(end, HPAGE_PMD_NR))
 					start++;
 				continue;
 			} else if (PageTransHuge(page)) {
-				if (index == round_down(end, HPAGE_PMD_NR)) {
+				if (indices[i] ==
+						round_down(end, HPAGE_PMD_NR)) {
 					/*
 					 * Range ends in the middle of THP:
 					 * zero out the page
@@ -911,7 +914,8 @@ static void shmem_undo_range(struct inode *inode, loff_t lstart, loff_t lend,
 					unlock_page(page);
 					continue;
 				}
-				index += HPAGE_PMD_NR - 1;
+				if (indices[i] + HPAGE_PMD_NR > index)
+					index = indices[i] + HPAGE_PMD_NR;
 				i += HPAGE_PMD_NR - 1;
 			}
 
@@ -923,7 +927,7 @@ static void shmem_undo_range(struct inode *inode, loff_t lstart, loff_t lend,
 				} else {
 					/* Page was replaced by swap: retry */
 					unlock_page(page);
-					index--;
+					index = indices[i];
 					break;
 				}
 			}
@@ -931,7 +935,6 @@ static void shmem_undo_range(struct inode *inode, loff_t lstart, loff_t lend,
 		}
 		pagevec_remove_exceptionals(&pvec);
 		pagevec_release(&pvec);
-		index++;
 	}
 
 	spin_lock_irq(&info->lock);
@@ -2487,31 +2490,33 @@ static pgoff_t shmem_seek_hole_data(struct address_space *mapping,
 	pgoff_t indices[PAGEVEC_SIZE];
 	bool done = false;
 	int i;
+	pgoff_t last;
 
 	pagevec_init(&pvec, 0);
 	pvec.nr = 1;		/* start small: we may be there already */
 	while (!done) {
-		pvec.nr = find_get_entries(mapping, index,
+		last = index;
+		pvec.nr = find_get_entries(mapping, &index,
 					pvec.nr, pvec.pages, indices);
 		if (!pvec.nr) {
 			if (whence == SEEK_DATA)
-				index = end;
+				last = end;
 			break;
 		}
-		for (i = 0; i < pvec.nr; i++, index++) {
-			if (index < indices[i]) {
+		for (i = 0; i < pvec.nr; i++, last++) {
+			if (last < indices[i]) {
 				if (whence == SEEK_HOLE) {
 					done = true;
 					break;
 				}
-				index = indices[i];
+				last = indices[i];
 			}
 			page = pvec.pages[i];
 			if (page && !radix_tree_exceptional_entry(page)) {
 				if (!PageUptodate(page))
 					page = NULL;
 			}
-			if (index >= end ||
+			if (last >= end ||
 			    (page && whence == SEEK_DATA) ||
 			    (!page && whence == SEEK_HOLE)) {
 				done = true;
@@ -2523,7 +2528,7 @@ static pgoff_t shmem_seek_hole_data(struct address_space *mapping,
 		pvec.nr = PAGEVEC_SIZE;
 		cond_resched();
 	}
-	return index;
+	return last;
 }
 
 static loff_t shmem_file_llseek(struct file *file, loff_t offset, int whence)
diff --git a/mm/swap.c b/mm/swap.c
index dc63970f79b9..6ba3dab6e905 100644
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -906,11 +906,11 @@ EXPORT_SYMBOL(__pagevec_lru_add);
  * not-present entries.
  *
  * pagevec_lookup_entries() returns the number of entries which were
- * found.
+ * found. It also updates @start to index the next page for the traversal.
  */
 unsigned pagevec_lookup_entries(struct pagevec *pvec,
 				struct address_space *mapping,
-				pgoff_t start, unsigned nr_pages,
+				pgoff_t *start, unsigned nr_pages,
 				pgoff_t *indices)
 {
 	pvec->nr = find_get_entries(mapping, start, nr_pages,
diff --git a/mm/truncate.c b/mm/truncate.c
index 2330223841fb..9efc82f18b74 100644
--- a/mm/truncate.c
+++ b/mm/truncate.c
@@ -289,26 +289,25 @@ void truncate_inode_pages_range(struct address_space *mapping,
 
 	pagevec_init(&pvec, 0);
 	index = start;
-	while (index < end && pagevec_lookup_entries(&pvec, mapping, index,
+	while (index < end && pagevec_lookup_entries(&pvec, mapping, &index,
 			min(end - index, (pgoff_t)PAGEVEC_SIZE),
 			indices)) {
 		for (i = 0; i < pagevec_count(&pvec); i++) {
 			struct page *page = pvec.pages[i];
 
 			/* We rely upon deletion not changing page->index */
-			index = indices[i];
-			if (index >= end)
+			if (indices[i] >= end)
 				break;
 
 			if (radix_tree_exceptional_entry(page)) {
-				truncate_exceptional_entry(mapping, index,
+				truncate_exceptional_entry(mapping, indices[i],
 							   page);
 				continue;
 			}
 
 			if (!trylock_page(page))
 				continue;
-			WARN_ON(page_to_index(page) != index);
+			WARN_ON(page_to_index(page) != indices[i]);
 			if (PageWriteback(page)) {
 				unlock_page(page);
 				continue;
@@ -319,7 +318,6 @@ void truncate_inode_pages_range(struct address_space *mapping,
 		pagevec_remove_exceptionals(&pvec);
 		pagevec_release(&pvec);
 		cond_resched();
-		index++;
 	}
 
 	if (partial_start) {
@@ -363,17 +361,19 @@ void truncate_inode_pages_range(struct address_space *mapping,
 
 	index = start;
 	for ( ; ; ) {
+		pgoff_t lookup_start = index;
+
 		cond_resched();
-		if (!pagevec_lookup_entries(&pvec, mapping, index,
+		if (!pagevec_lookup_entries(&pvec, mapping, &index,
 			min(end - index, (pgoff_t)PAGEVEC_SIZE), indices)) {
 			/* If all gone from start onwards, we're done */
-			if (index == start)
+			if (lookup_start == start)
 				break;
 			/* Otherwise restart to make sure all gone */
 			index = start;
 			continue;
 		}
-		if (index == start && indices[0] >= end) {
+		if (lookup_start == start && indices[0] >= end) {
 			/* All gone out of hole to be punched, we're done */
 			pagevec_remove_exceptionals(&pvec);
 			pagevec_release(&pvec);
@@ -383,28 +383,26 @@ void truncate_inode_pages_range(struct address_space *mapping,
 			struct page *page = pvec.pages[i];
 
 			/* We rely upon deletion not changing page->index */
-			index = indices[i];
-			if (index >= end) {
+			if (indices[i] >= end) {
 				/* Restart punch to make sure all gone */
-				index = start - 1;
+				index = start;
 				break;
 			}
 
 			if (radix_tree_exceptional_entry(page)) {
-				truncate_exceptional_entry(mapping, index,
+				truncate_exceptional_entry(mapping, indices[i],
 							   page);
 				continue;
 			}
 
 			lock_page(page);
-			WARN_ON(page_to_index(page) != index);
+			WARN_ON(page_to_index(page) != indices[i]);
 			wait_on_page_writeback(page);
 			truncate_inode_page(mapping, page);
 			unlock_page(page);
 		}
 		pagevec_remove_exceptionals(&pvec);
 		pagevec_release(&pvec);
-		index++;
 	}
 
 out:
@@ -501,44 +499,44 @@ unsigned long invalidate_mapping_pages(struct address_space *mapping,
 	int i;
 
 	pagevec_init(&pvec, 0);
-	while (index <= end && pagevec_lookup_entries(&pvec, mapping, index,
+	while (index <= end && pagevec_lookup_entries(&pvec, mapping, &index,
 			min(end - index, (pgoff_t)PAGEVEC_SIZE - 1) + 1,
 			indices)) {
 		for (i = 0; i < pagevec_count(&pvec); i++) {
 			struct page *page = pvec.pages[i];
 
 			/* We rely upon deletion not changing page->index */
-			index = indices[i];
-			if (index > end)
+			if (indices[i] > end)
 				break;
 
 			if (radix_tree_exceptional_entry(page)) {
-				invalidate_exceptional_entry(mapping, index,
-							     page);
+				invalidate_exceptional_entry(mapping,
+							     indices[i], page);
 				continue;
 			}
 
 			if (!trylock_page(page))
 				continue;
 
-			WARN_ON(page_to_index(page) != index);
+			WARN_ON(page_to_index(page) != indices[i]);
 
 			/* Middle of THP: skip */
 			if (PageTransTail(page)) {
 				unlock_page(page);
 				continue;
 			} else if (PageTransHuge(page)) {
-				index += HPAGE_PMD_NR - 1;
-				i += HPAGE_PMD_NR - 1;
+				if (index < indices[i] + HPAGE_PMD_NR)
+					index = indices[i] + HPAGE_PMD_NR;
 				/*
 				 * 'end' is in the middle of THP. Don't
 				 * invalidate the page as the part outside of
 				 * 'end' could be still useful.
 				 */
-				if (index > end) {
+				if (indices[i] + HPAGE_PMD_NR - 1 > end) {
 					unlock_page(page);
-					continue;
+					break;
 				}
+				i += HPAGE_PMD_NR - 1;
 			}
 
 			ret = invalidate_inode_page(page);
@@ -554,7 +552,6 @@ unsigned long invalidate_mapping_pages(struct address_space *mapping,
 		pagevec_remove_exceptionals(&pvec);
 		pagevec_release(&pvec);
 		cond_resched();
-		index++;
 	}
 	return count;
 }
@@ -632,26 +629,25 @@ int invalidate_inode_pages2_range(struct address_space *mapping,
 
 	pagevec_init(&pvec, 0);
 	index = start;
-	while (index <= end && pagevec_lookup_entries(&pvec, mapping, index,
+	while (index <= end && pagevec_lookup_entries(&pvec, mapping, &index,
 			min(end - index, (pgoff_t)PAGEVEC_SIZE - 1) + 1,
 			indices)) {
 		for (i = 0; i < pagevec_count(&pvec); i++) {
 			struct page *page = pvec.pages[i];
 
 			/* We rely upon deletion not changing page->index */
-			index = indices[i];
-			if (index > end)
+			if (indices[i] > end)
 				break;
 
 			if (radix_tree_exceptional_entry(page)) {
 				if (!invalidate_exceptional_entry2(mapping,
-								   index, page))
+							indices[i], page))
 					ret = -EBUSY;
 				continue;
 			}
 
 			lock_page(page);
-			WARN_ON(page_to_index(page) != index);
+			WARN_ON(page_to_index(page) != indices[i]);
 			if (page->mapping != mapping) {
 				unlock_page(page);
 				continue;
@@ -663,8 +659,8 @@ int invalidate_inode_pages2_range(struct address_space *mapping,
 					 * Zap the rest of the file in one hit.
 					 */
 					unmap_mapping_range(mapping,
-					   (loff_t)index << PAGE_SHIFT,
-					   (loff_t)(1 + end - index)
+					   (loff_t)indices[i] << PAGE_SHIFT,
+					   (loff_t)(1 + end - indices[i])
 							 << PAGE_SHIFT,
 							 0);
 					did_range_unmap = 1;
@@ -673,7 +669,7 @@ int invalidate_inode_pages2_range(struct address_space *mapping,
 					 * Just zap this page
 					 */
 					unmap_mapping_range(mapping,
-					   (loff_t)index << PAGE_SHIFT,
+					   (loff_t)indices[i] << PAGE_SHIFT,
 					   PAGE_SIZE, 0);
 				}
 			}
@@ -690,7 +686,6 @@ int invalidate_inode_pages2_range(struct address_space *mapping,
 		pagevec_remove_exceptionals(&pvec);
 		pagevec_release(&pvec);
 		cond_resched();
-		index++;
 	}
 	/*
 	 * For DAX we invalidate page tables after invalidating radix tree.  We
-- 
2.12.3

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 30/35] mm: Implement find_get_entries_range()
  2017-06-01  9:32 [PATCH 00/35 v1] pagevec API cleanups Jan Kara
                   ` (28 preceding siblings ...)
  2017-06-01  9:32 ` [PATCH 29/35] mm: Make pagevec_lookup_entries() update index Jan Kara
@ 2017-06-01  9:32 ` Jan Kara
  2017-06-01  9:32 ` [PATCH 31/35] shmem: Convert to pagevec_lookup_entries_range() Jan Kara
                   ` (6 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Jan Kara @ 2017-06-01  9:32 UTC (permalink / raw)
  To: linux-mm
  Cc: Hugh Dickins, David Howells, linux-afs, Ryusuke Konishi,
	linux-nilfs, Bob Peterson, cluster-devel, Jaegeuk Kim,
	linux-f2fs-devel, tytso, linux-ext4, Ilya Dryomov, Yan, Zheng,
	ceph-devel, linux-btrfs, David Sterba, Darrick J . Wong,
	linux-xfs, Nadia Yvette Chambers, Jan Kara

Implement a variant of find_get_entries() that stops iterating at
given index. Some callers want this, so let's provide the interface.
Also it makes the interface consistent with find_get_pages().

Signed-off-by: Jan Kara <jack@suse.cz>
---
 include/linux/pagemap.h | 13 ++++++++++---
 include/linux/pagevec.h | 12 ++++++++++--
 mm/filemap.c            | 32 ++++++++++++++++++++++++--------
 mm/swap.c               | 11 ++++++-----
 4 files changed, 50 insertions(+), 18 deletions(-)

diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
index 283d191c18be..df128a56f44b 100644
--- a/include/linux/pagemap.h
+++ b/include/linux/pagemap.h
@@ -333,9 +333,16 @@ static inline struct page *grab_cache_page_nowait(struct address_space *mapping,
 
 struct page *find_get_entry(struct address_space *mapping, pgoff_t offset);
 struct page *find_lock_entry(struct address_space *mapping, pgoff_t offset);
-unsigned find_get_entries(struct address_space *mapping, pgoff_t *start,
-			  unsigned int nr_entries, struct page **entries,
-			  pgoff_t *indices);
+unsigned find_get_entries_range(struct address_space *mapping, pgoff_t *start,
+			pgoff_t end, unsigned int nr_entries,
+			struct page **entries, pgoff_t *indices);
+static inline unsigned find_get_entries(struct address_space *mapping,
+			pgoff_t *start, unsigned int nr_entries,
+			struct page **entries, pgoff_t *indices)
+{
+	return find_get_entries_range(mapping, start, (pgoff_t)-1, nr_entries,
+				      entries, indices);
+}
 unsigned find_get_pages_range(struct address_space *mapping, pgoff_t *start,
 			pgoff_t end, unsigned int nr_pages,
 			struct page **pages);
diff --git a/include/linux/pagevec.h b/include/linux/pagevec.h
index 3798c142338d..93308689d6a7 100644
--- a/include/linux/pagevec.h
+++ b/include/linux/pagevec.h
@@ -22,10 +22,18 @@ struct pagevec {
 
 void __pagevec_release(struct pagevec *pvec);
 void __pagevec_lru_add(struct pagevec *pvec);
-unsigned pagevec_lookup_entries(struct pagevec *pvec,
+unsigned pagevec_lookup_entries_range(struct pagevec *pvec,
+				struct address_space *mapping,
+				pgoff_t *start, pgoff_t end,
+				unsigned nr_entries, pgoff_t *indices);
+static inline unsigned pagevec_lookup_entries(struct pagevec *pvec,
 				struct address_space *mapping,
 				pgoff_t *start, unsigned nr_entries,
-				pgoff_t *indices);
+				pgoff_t *indices)
+{
+	return pagevec_lookup_entries_range(pvec, mapping, start, (pgoff_t)-1,
+					    nr_entries, indices);
+}
 void pagevec_remove_exceptionals(struct pagevec *pvec);
 unsigned pagevec_lookup_range(struct pagevec *pvec,
 			      struct address_space *mapping,
diff --git a/mm/filemap.c b/mm/filemap.c
index de12b7355821..e55100459710 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -1354,9 +1354,10 @@ struct page *pagecache_get_page(struct address_space *mapping, pgoff_t offset,
 EXPORT_SYMBOL(pagecache_get_page);
 
 /**
- * find_get_entries - gang pagecache lookup
+ * find_get_entries_range - gang pagecache lookup
  * @mapping:	The address_space to search
  * @start:	The starting page cache index
+ * @end:	The final page cache index (inclusive)
  * @nr_entries:	The maximum number of entries
  * @entries:	Where the resulting entries are placed
  * @indices:	The cache indices corresponding to the entries in @entries
@@ -1376,9 +1377,9 @@ EXPORT_SYMBOL(pagecache_get_page);
  * find_get_entries() returns the number of pages and shadow entries which were
  * found. It also updates @start to index the next page for the traversal.
  */
-unsigned find_get_entries(struct address_space *mapping,
-			  pgoff_t *start, unsigned int nr_entries,
-			  struct page **entries, pgoff_t *indices)
+unsigned find_get_entries_range(struct address_space *mapping,
+			pgoff_t *start, pgoff_t end, unsigned int nr_entries,
+			struct page **entries, pgoff_t *indices)
 {
 	void **slot;
 	unsigned int ret = 0;
@@ -1390,6 +1391,9 @@ unsigned find_get_entries(struct address_space *mapping,
 	rcu_read_lock();
 	radix_tree_for_each_slot(slot, &mapping->page_tree, &iter, *start) {
 		struct page *head, *page;
+
+		if (iter.index > end)
+			break;
 repeat:
 		page = radix_tree_deref_slot(slot);
 		if (unlikely(!page))
@@ -1425,13 +1429,25 @@ unsigned find_get_entries(struct address_space *mapping,
 export:
 		indices[ret] = iter.index;
 		entries[ret] = page;
-		if (++ret == nr_entries)
-			break;
+		if (++ret == nr_entries) {
+			*start = indices[ret - 1] + 1;
+			goto out;
+		}
 	}
+
+	/*
+	 * We come here when there is no page beyond @end. We take care to not
+	 * overflow the index @start as it confuses some of the callers. This
+	 * breaks the iteration when there is page at index -1 but that is
+	 * already broken anyway.
+	 */
+	if (end == (pgoff_t)-1)
+		*start = (pgoff_t)-1;
+	else
+		*start = end + 1;
+out:
 	rcu_read_unlock();
 
-	if (ret)
-		*start = indices[ret - 1] + 1;
 	return ret;
 }
 
diff --git a/mm/swap.c b/mm/swap.c
index 6ba3dab6e905..88c7eb4e97db 100644
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -889,10 +889,11 @@ void __pagevec_lru_add(struct pagevec *pvec)
 EXPORT_SYMBOL(__pagevec_lru_add);
 
 /**
- * pagevec_lookup_entries - gang pagecache lookup
+ * pagevec_lookup_entries_range - gang pagecache lookup
  * @pvec:	Where the resulting entries are placed
  * @mapping:	The address_space to search
  * @start:	The starting entry index
+ * @end:	The final entry index (inclusive)
  * @nr_entries:	The maximum number of entries
  * @indices:	The cache indices corresponding to the entries in @pvec
  *
@@ -908,13 +909,13 @@ EXPORT_SYMBOL(__pagevec_lru_add);
  * pagevec_lookup_entries() returns the number of entries which were
  * found. It also updates @start to index the next page for the traversal.
  */
-unsigned pagevec_lookup_entries(struct pagevec *pvec,
+unsigned pagevec_lookup_entries_range(struct pagevec *pvec,
 				struct address_space *mapping,
-				pgoff_t *start, unsigned nr_pages,
+				pgoff_t *start, pgoff_t end, unsigned nr_pages,
 				pgoff_t *indices)
 {
-	pvec->nr = find_get_entries(mapping, start, nr_pages,
-				    pvec->pages, indices);
+	pvec->nr = find_get_entries_range(mapping, start, end, nr_pages,
+					  pvec->pages, indices);
 	return pagevec_count(pvec);
 }
 
-- 
2.12.3

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 31/35] shmem: Convert to pagevec_lookup_entries_range()
  2017-06-01  9:32 [PATCH 00/35 v1] pagevec API cleanups Jan Kara
                   ` (29 preceding siblings ...)
  2017-06-01  9:32 ` [PATCH 30/35] mm: Implement find_get_entries_range() Jan Kara
@ 2017-06-01  9:32 ` Jan Kara
  2017-06-01 13:55   ` kbuild test robot
  2017-06-01  9:32 ` [PATCH 32/35] mm: Convert truncate code " Jan Kara
                   ` (5 subsequent siblings)
  36 siblings, 1 reply; 43+ messages in thread
From: Jan Kara @ 2017-06-01  9:32 UTC (permalink / raw)
  To: linux-mm
  Cc: Hugh Dickins, David Howells, linux-afs, Ryusuke Konishi,
	linux-nilfs, Bob Peterson, cluster-devel, Jaegeuk Kim,
	linux-f2fs-devel, tytso, linux-ext4, Ilya Dryomov, Yan, Zheng,
	ceph-devel, linux-btrfs, David Sterba, Darrick J . Wong,
	linux-xfs, Nadia Yvette Chambers, Jan Kara

Convert radix tree scanners to use pagevec_lookup_entries_range() and
find_get_entries_range() since they all want only entries from given
range.

CC: Hugh Dickins <hughd@google.com>
Signed-off-by: Jan Kara <jack@suse.cz>
---
 mm/shmem.c | 23 +++++++----------------
 1 file changed, 7 insertions(+), 16 deletions(-)

diff --git a/mm/shmem.c b/mm/shmem.c
index f9c4afbdd70c..e5ea044aae24 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -768,16 +768,12 @@ static void shmem_undo_range(struct inode *inode, loff_t lstart, loff_t lend,
 	pagevec_init(&pvec, 0);
 	index = start;
 	while (index < end) {
-		if (!pagevec_lookup_entries(&pvec, mapping, &index,
-				min(end - index, (pgoff_t)PAGEVEC_SIZE),
-				indices))
+		if (!pagevec_lookup_entries_range(&pvec, mapping, &index,
+				end - 1, PAGEVEC_SIZE, indices))
 			break;
 		for (i = 0; i < pagevec_count(&pvec); i++) {
 			struct page *page = pvec.pages[i];
 
-			if (indices[i] >= end)
-				break;
-
 			if (radix_tree_exceptional_entry(page)) {
 				if (unfalloc)
 					continue;
@@ -860,9 +856,8 @@ static void shmem_undo_range(struct inode *inode, loff_t lstart, loff_t lend,
 
 		cond_resched();
 
-		if (!pagevec_lookup_entries(&pvec, mapping, &index,
-				min(end - index, (pgoff_t)PAGEVEC_SIZE),
-				indices)) {
+		if (!pagevec_lookup_entries_range(&pvec, mapping, &index,
+				end - 1, PAGEVEC_SIZE, indices)) {
 			/* If all gone or hole-punch or unfalloc, we're done */
 			if (lookup_start == start || end != -1)
 				break;
@@ -873,9 +868,6 @@ static void shmem_undo_range(struct inode *inode, loff_t lstart, loff_t lend,
 		for (i = 0; i < pagevec_count(&pvec); i++) {
 			struct page *page = pvec.pages[i];
 
-			if (indices[i] >= end)
-				break;
-
 			if (radix_tree_exceptional_entry(page)) {
 				if (unfalloc)
 					continue;
@@ -2494,9 +2486,9 @@ static pgoff_t shmem_seek_hole_data(struct address_space *mapping,
 
 	pagevec_init(&pvec, 0);
 	pvec.nr = 1;		/* start small: we may be there already */
-	while (!done) {
+	while (!done && index < end) {
 		last = index;
-		pvec.nr = find_get_entries(mapping, &index,
+		pvec.nr = find_get_entries_range(mapping, &index, end - 1,
 					pvec.nr, pvec.pages, indices);
 		if (!pvec.nr) {
 			if (whence == SEEK_DATA)
@@ -2516,8 +2508,7 @@ static pgoff_t shmem_seek_hole_data(struct address_space *mapping,
 				if (!PageUptodate(page))
 					page = NULL;
 			}
-			if (last >= end ||
-			    (page && whence == SEEK_DATA) ||
+			if ((page && whence == SEEK_DATA) ||
 			    (!page && whence == SEEK_HOLE)) {
 				done = true;
 				break;
-- 
2.12.3

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 32/35] mm: Convert truncate code to pagevec_lookup_entries_range()
  2017-06-01  9:32 [PATCH 00/35 v1] pagevec API cleanups Jan Kara
                   ` (30 preceding siblings ...)
  2017-06-01  9:32 ` [PATCH 31/35] shmem: Convert to pagevec_lookup_entries_range() Jan Kara
@ 2017-06-01  9:32 ` Jan Kara
  2017-06-01  9:32 ` [PATCH 33/35] mm: Remove nr_entries argument from pagevec_lookup_entries{,_range}() Jan Kara
                   ` (4 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Jan Kara @ 2017-06-01  9:32 UTC (permalink / raw)
  To: linux-mm
  Cc: Hugh Dickins, David Howells, linux-afs, Ryusuke Konishi,
	linux-nilfs, Bob Peterson, cluster-devel, Jaegeuk Kim,
	linux-f2fs-devel, tytso, linux-ext4, Ilya Dryomov, Yan, Zheng,
	ceph-devel, linux-btrfs, David Sterba, Darrick J . Wong,
	linux-xfs, Nadia Yvette Chambers, Jan Kara

All radix tree scanning code in truncate paths is interested only in
pages from given range. Convert them to pagevec_lookup_entries_range().

Signed-off-by: Jan Kara <jack@suse.cz>
---
 mm/truncate.c | 52 +++++++++-------------------------------------------
 1 file changed, 9 insertions(+), 43 deletions(-)

diff --git a/mm/truncate.c b/mm/truncate.c
index 9efc82f18b74..31d5c5f3da30 100644
--- a/mm/truncate.c
+++ b/mm/truncate.c
@@ -289,16 +289,11 @@ void truncate_inode_pages_range(struct address_space *mapping,
 
 	pagevec_init(&pvec, 0);
 	index = start;
-	while (index < end && pagevec_lookup_entries(&pvec, mapping, &index,
-			min(end - index, (pgoff_t)PAGEVEC_SIZE),
-			indices)) {
+	while (index < end && pagevec_lookup_entries_range(&pvec, mapping,
+			&index, end - 1, PAGEVEC_SIZE, indices)) {
 		for (i = 0; i < pagevec_count(&pvec); i++) {
 			struct page *page = pvec.pages[i];
 
-			/* We rely upon deletion not changing page->index */
-			if (indices[i] >= end)
-				break;
-
 			if (radix_tree_exceptional_entry(page)) {
 				truncate_exceptional_entry(mapping, indices[i],
 							   page);
@@ -352,20 +347,14 @@ void truncate_inode_pages_range(struct address_space *mapping,
 			put_page(page);
 		}
 	}
-	/*
-	 * If the truncation happened within a single page no pages
-	 * will be released, just zeroed, so we can bail out now.
-	 */
-	if (start >= end)
-		goto out;
 
 	index = start;
-	for ( ; ; ) {
+	while (index < end) {
 		pgoff_t lookup_start = index;
 
 		cond_resched();
-		if (!pagevec_lookup_entries(&pvec, mapping, &index,
-			min(end - index, (pgoff_t)PAGEVEC_SIZE), indices)) {
+		if (!pagevec_lookup_entries_range(&pvec, mapping, &index,
+					end - 1, PAGEVEC_SIZE, indices)) {
 			/* If all gone from start onwards, we're done */
 			if (lookup_start == start)
 				break;
@@ -373,22 +362,9 @@ void truncate_inode_pages_range(struct address_space *mapping,
 			index = start;
 			continue;
 		}
-		if (lookup_start == start && indices[0] >= end) {
-			/* All gone out of hole to be punched, we're done */
-			pagevec_remove_exceptionals(&pvec);
-			pagevec_release(&pvec);
-			break;
-		}
 		for (i = 0; i < pagevec_count(&pvec); i++) {
 			struct page *page = pvec.pages[i];
 
-			/* We rely upon deletion not changing page->index */
-			if (indices[i] >= end) {
-				/* Restart punch to make sure all gone */
-				index = start;
-				break;
-			}
-
 			if (radix_tree_exceptional_entry(page)) {
 				truncate_exceptional_entry(mapping, indices[i],
 							   page);
@@ -499,16 +475,11 @@ unsigned long invalidate_mapping_pages(struct address_space *mapping,
 	int i;
 
 	pagevec_init(&pvec, 0);
-	while (index <= end && pagevec_lookup_entries(&pvec, mapping, &index,
-			min(end - index, (pgoff_t)PAGEVEC_SIZE - 1) + 1,
-			indices)) {
+	while (index <= end && pagevec_lookup_entries_range(&pvec, mapping,
+			&index, end, PAGEVEC_SIZE, indices)) {
 		for (i = 0; i < pagevec_count(&pvec); i++) {
 			struct page *page = pvec.pages[i];
 
-			/* We rely upon deletion not changing page->index */
-			if (indices[i] > end)
-				break;
-
 			if (radix_tree_exceptional_entry(page)) {
 				invalidate_exceptional_entry(mapping,
 							     indices[i], page);
@@ -629,16 +600,11 @@ int invalidate_inode_pages2_range(struct address_space *mapping,
 
 	pagevec_init(&pvec, 0);
 	index = start;
-	while (index <= end && pagevec_lookup_entries(&pvec, mapping, &index,
-			min(end - index, (pgoff_t)PAGEVEC_SIZE - 1) + 1,
-			indices)) {
+	while (index <= end && pagevec_lookup_entries_range(&pvec, mapping,
+			&index, end, PAGEVEC_SIZE, indices)) {
 		for (i = 0; i < pagevec_count(&pvec); i++) {
 			struct page *page = pvec.pages[i];
 
-			/* We rely upon deletion not changing page->index */
-			if (indices[i] > end)
-				break;
-
 			if (radix_tree_exceptional_entry(page)) {
 				if (!invalidate_exceptional_entry2(mapping,
 							indices[i], page))
-- 
2.12.3

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 33/35] mm: Remove nr_entries argument from pagevec_lookup_entries{,_range}()
  2017-06-01  9:32 [PATCH 00/35 v1] pagevec API cleanups Jan Kara
                   ` (31 preceding siblings ...)
  2017-06-01  9:32 ` [PATCH 32/35] mm: Convert truncate code " Jan Kara
@ 2017-06-01  9:32 ` Jan Kara
  2017-06-01  9:32 ` [PATCH 34/35] mm: Make find_get_entries_tag() update index Jan Kara
                   ` (3 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Jan Kara @ 2017-06-01  9:32 UTC (permalink / raw)
  To: linux-mm
  Cc: Hugh Dickins, David Howells, linux-afs, Ryusuke Konishi,
	linux-nilfs, Bob Peterson, cluster-devel, Jaegeuk Kim,
	linux-f2fs-devel, tytso, linux-ext4, Ilya Dryomov, Yan, Zheng,
	ceph-devel, linux-btrfs, David Sterba, Darrick J . Wong,
	linux-xfs, Nadia Yvette Chambers, Jan Kara

All users pass PAGEVEC_SIZE as the number of entries now. Remove the
argument.

Signed-off-by: Jan Kara <jack@suse.cz>
---
 include/linux/pagevec.h | 7 +++----
 mm/shmem.c              | 4 ++--
 mm/swap.c               | 6 ++----
 mm/truncate.c           | 8 ++++----
 4 files changed, 11 insertions(+), 14 deletions(-)

diff --git a/include/linux/pagevec.h b/include/linux/pagevec.h
index 93308689d6a7..f765fc5eca31 100644
--- a/include/linux/pagevec.h
+++ b/include/linux/pagevec.h
@@ -25,14 +25,13 @@ void __pagevec_lru_add(struct pagevec *pvec);
 unsigned pagevec_lookup_entries_range(struct pagevec *pvec,
 				struct address_space *mapping,
 				pgoff_t *start, pgoff_t end,
-				unsigned nr_entries, pgoff_t *indices);
+				pgoff_t *indices);
 static inline unsigned pagevec_lookup_entries(struct pagevec *pvec,
 				struct address_space *mapping,
-				pgoff_t *start, unsigned nr_entries,
-				pgoff_t *indices)
+				pgoff_t *start, pgoff_t *indices)
 {
 	return pagevec_lookup_entries_range(pvec, mapping, start, (pgoff_t)-1,
-					    nr_entries, indices);
+					    indices);
 }
 void pagevec_remove_exceptionals(struct pagevec *pvec);
 unsigned pagevec_lookup_range(struct pagevec *pvec,
diff --git a/mm/shmem.c b/mm/shmem.c
index e5ea044aae24..dd8144230ecf 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -769,7 +769,7 @@ static void shmem_undo_range(struct inode *inode, loff_t lstart, loff_t lend,
 	index = start;
 	while (index < end) {
 		if (!pagevec_lookup_entries_range(&pvec, mapping, &index,
-				end - 1, PAGEVEC_SIZE, indices))
+				end - 1, indices))
 			break;
 		for (i = 0; i < pagevec_count(&pvec); i++) {
 			struct page *page = pvec.pages[i];
@@ -857,7 +857,7 @@ static void shmem_undo_range(struct inode *inode, loff_t lstart, loff_t lend,
 		cond_resched();
 
 		if (!pagevec_lookup_entries_range(&pvec, mapping, &index,
-				end - 1, PAGEVEC_SIZE, indices)) {
+				end - 1, indices)) {
 			/* If all gone or hole-punch or unfalloc, we're done */
 			if (lookup_start == start || end != -1)
 				break;
diff --git a/mm/swap.c b/mm/swap.c
index 88c7eb4e97db..1640bbb34e59 100644
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -894,7 +894,6 @@ EXPORT_SYMBOL(__pagevec_lru_add);
  * @mapping:	The address_space to search
  * @start:	The starting entry index
  * @end:	The final entry index (inclusive)
- * @nr_entries:	The maximum number of entries
  * @indices:	The cache indices corresponding to the entries in @pvec
  *
  * pagevec_lookup_entries() will search for and return a group of up
@@ -911,10 +910,9 @@ EXPORT_SYMBOL(__pagevec_lru_add);
  */
 unsigned pagevec_lookup_entries_range(struct pagevec *pvec,
 				struct address_space *mapping,
-				pgoff_t *start, pgoff_t end, unsigned nr_pages,
-				pgoff_t *indices)
+				pgoff_t *start, pgoff_t end, pgoff_t *indices)
 {
-	pvec->nr = find_get_entries_range(mapping, start, end, nr_pages,
+	pvec->nr = find_get_entries_range(mapping, start, end, PAGEVEC_SIZE,
 					  pvec->pages, indices);
 	return pagevec_count(pvec);
 }
diff --git a/mm/truncate.c b/mm/truncate.c
index 31d5c5f3da30..d35531d83cb3 100644
--- a/mm/truncate.c
+++ b/mm/truncate.c
@@ -290,7 +290,7 @@ void truncate_inode_pages_range(struct address_space *mapping,
 	pagevec_init(&pvec, 0);
 	index = start;
 	while (index < end && pagevec_lookup_entries_range(&pvec, mapping,
-			&index, end - 1, PAGEVEC_SIZE, indices)) {
+			&index, end - 1, indices)) {
 		for (i = 0; i < pagevec_count(&pvec); i++) {
 			struct page *page = pvec.pages[i];
 
@@ -354,7 +354,7 @@ void truncate_inode_pages_range(struct address_space *mapping,
 
 		cond_resched();
 		if (!pagevec_lookup_entries_range(&pvec, mapping, &index,
-					end - 1, PAGEVEC_SIZE, indices)) {
+					end - 1, indices)) {
 			/* If all gone from start onwards, we're done */
 			if (lookup_start == start)
 				break;
@@ -476,7 +476,7 @@ unsigned long invalidate_mapping_pages(struct address_space *mapping,
 
 	pagevec_init(&pvec, 0);
 	while (index <= end && pagevec_lookup_entries_range(&pvec, mapping,
-			&index, end, PAGEVEC_SIZE, indices)) {
+			&index, end, indices)) {
 		for (i = 0; i < pagevec_count(&pvec); i++) {
 			struct page *page = pvec.pages[i];
 
@@ -601,7 +601,7 @@ int invalidate_inode_pages2_range(struct address_space *mapping,
 	pagevec_init(&pvec, 0);
 	index = start;
 	while (index <= end && pagevec_lookup_entries_range(&pvec, mapping,
-			&index, end, PAGEVEC_SIZE, indices)) {
+			&index, end, indices)) {
 		for (i = 0; i < pagevec_count(&pvec); i++) {
 			struct page *page = pvec.pages[i];
 
-- 
2.12.3

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 34/35] mm: Make find_get_entries_tag() update index
  2017-06-01  9:32 [PATCH 00/35 v1] pagevec API cleanups Jan Kara
                   ` (32 preceding siblings ...)
  2017-06-01  9:32 ` [PATCH 33/35] mm: Remove nr_entries argument from pagevec_lookup_entries{,_range}() Jan Kara
@ 2017-06-01  9:32 ` Jan Kara
  2017-06-01  9:32 ` [PATCH 35/35] mm: Implement find_get_entries_range_tag() Jan Kara
                   ` (2 subsequent siblings)
  36 siblings, 0 replies; 43+ messages in thread
From: Jan Kara @ 2017-06-01  9:32 UTC (permalink / raw)
  To: linux-mm
  Cc: Hugh Dickins, David Howells, linux-afs, Ryusuke Konishi,
	linux-nilfs, Bob Peterson, cluster-devel, Jaegeuk Kim,
	linux-f2fs-devel, tytso, linux-ext4, Ilya Dryomov, Yan, Zheng,
	ceph-devel, linux-btrfs, David Sterba, Darrick J . Wong,
	linux-xfs, Nadia Yvette Chambers, Jan Kara

Make find_get_entries_tag() update 'start' to index the next page for
iteration.

Signed-off-by: Jan Kara <jack@suse.cz>
---
 fs/dax.c                | 3 +--
 include/linux/pagemap.h | 2 +-
 mm/filemap.c            | 8 ++++++--
 3 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/fs/dax.c b/fs/dax.c
index c204445a69b0..4b295c544fd4 100644
--- a/fs/dax.c
+++ b/fs/dax.c
@@ -841,7 +841,7 @@ int dax_writeback_mapping_range(struct address_space *mapping,
 
 	pagevec_init(&pvec, 0);
 	while (!done) {
-		pvec.nr = find_get_entries_tag(mapping, start_index,
+		pvec.nr = find_get_entries_tag(mapping, &start_index,
 				PAGECACHE_TAG_TOWRITE, PAGEVEC_SIZE,
 				pvec.pages, indices);
 
@@ -859,7 +859,6 @@ int dax_writeback_mapping_range(struct address_space *mapping,
 			if (ret < 0)
 				goto out;
 		}
-		start_index = indices[pvec.nr - 1] + 1;
 	}
 out:
 	put_dax(dax_dev);
diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
index df128a56f44b..1dc7e54ec32a 100644
--- a/include/linux/pagemap.h
+++ b/include/linux/pagemap.h
@@ -365,7 +365,7 @@ static inline unsigned find_get_pages_tag(struct address_space *mapping,
 	return find_get_pages_range_tag(mapping, index, (pgoff_t)-1, tag,
 					nr_pages, pages);
 }
-unsigned find_get_entries_tag(struct address_space *mapping, pgoff_t start,
+unsigned find_get_entries_tag(struct address_space *mapping, pgoff_t *start,
 			int tag, unsigned int nr_entries,
 			struct page **entries, pgoff_t *indices);
 
diff --git a/mm/filemap.c b/mm/filemap.c
index e55100459710..3eb05c91c07a 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -1731,7 +1731,7 @@ EXPORT_SYMBOL(find_get_pages_range_tag);
  * Like find_get_entries, except we only return entries which are tagged with
  * @tag.
  */
-unsigned find_get_entries_tag(struct address_space *mapping, pgoff_t start,
+unsigned find_get_entries_tag(struct address_space *mapping, pgoff_t *start,
 			int tag, unsigned int nr_entries,
 			struct page **entries, pgoff_t *indices)
 {
@@ -1744,7 +1744,7 @@ unsigned find_get_entries_tag(struct address_space *mapping, pgoff_t start,
 
 	rcu_read_lock();
 	radix_tree_for_each_tagged(slot, &mapping->page_tree,
-				   &iter, start, tag) {
+				   &iter, *start, tag) {
 		struct page *head, *page;
 repeat:
 		page = radix_tree_deref_slot(slot);
@@ -1786,6 +1786,10 @@ unsigned find_get_entries_tag(struct address_space *mapping, pgoff_t start,
 			break;
 	}
 	rcu_read_unlock();
+
+	if (ret)
+		*start = indices[ret - 1] + 1;
+
 	return ret;
 }
 EXPORT_SYMBOL(find_get_entries_tag);
-- 
2.12.3

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [PATCH 35/35] mm: Implement find_get_entries_range_tag()
  2017-06-01  9:32 [PATCH 00/35 v1] pagevec API cleanups Jan Kara
                   ` (33 preceding siblings ...)
  2017-06-01  9:32 ` [PATCH 34/35] mm: Make find_get_entries_tag() update index Jan Kara
@ 2017-06-01  9:32 ` Jan Kara
  2017-06-01 10:26 ` [PATCH 01/35] fscache: Remove unused ->now_uncached callback David Howells
  2017-06-01 11:36 ` [Cluster-devel] [PATCH 00/35 v1] pagevec API cleanups Christoph Hellwig
  36 siblings, 0 replies; 43+ messages in thread
From: Jan Kara @ 2017-06-01  9:32 UTC (permalink / raw)
  To: linux-mm
  Cc: Hugh Dickins, David Howells, linux-afs, Ryusuke Konishi,
	linux-nilfs, Bob Peterson, cluster-devel, Jaegeuk Kim,
	linux-f2fs-devel, tytso, linux-ext4, Ilya Dryomov, Yan, Zheng,
	ceph-devel, linux-btrfs, David Sterba, Darrick J . Wong,
	linux-xfs, Nadia Yvette Chambers, Jan Kara

Implement find_get_entries_range_tag() (actually convert
find_get_entries_tag() tag to it as the only user of
find_get_entries_tag() needs a ranged lookup) and use it in DAX which is
the only user of this interface. This is mostly for consistency with
other page/entry iteration interfaces.

Signed-off-by: Jan Kara <jack@suse.cz>
---
 fs/dax.c                | 12 +++---------
 include/linux/pagemap.h |  3 ++-
 mm/filemap.c            | 36 ++++++++++++++++++++++++++----------
 3 files changed, 31 insertions(+), 20 deletions(-)

diff --git a/fs/dax.c b/fs/dax.c
index 4b295c544fd4..acf17b55f76b 100644
--- a/fs/dax.c
+++ b/fs/dax.c
@@ -819,7 +819,6 @@ int dax_writeback_mapping_range(struct address_space *mapping,
 	pgoff_t indices[PAGEVEC_SIZE];
 	struct dax_device *dax_dev;
 	struct pagevec pvec;
-	bool done = false;
 	int i, ret = 0;
 
 	if (WARN_ON_ONCE(inode->i_blkbits != PAGE_SHIFT))
@@ -840,20 +839,15 @@ int dax_writeback_mapping_range(struct address_space *mapping,
 	tag_pages_for_writeback(mapping, start_index, end_index);
 
 	pagevec_init(&pvec, 0);
-	while (!done) {
-		pvec.nr = find_get_entries_tag(mapping, &start_index,
-				PAGECACHE_TAG_TOWRITE, PAGEVEC_SIZE,
+	while (start_index <= end_index) {
+		pvec.nr = find_get_entries_range_tag(mapping, &start_index,
+				end_index, PAGECACHE_TAG_TOWRITE, PAGEVEC_SIZE,
 				pvec.pages, indices);
 
 		if (pvec.nr == 0)
 			break;
 
 		for (i = 0; i < pvec.nr; i++) {
-			if (indices[i] > end_index) {
-				done = true;
-				break;
-			}
-
 			ret = dax_writeback_one(bdev, dax_dev, mapping,
 					indices[i], pvec.pages[i]);
 			if (ret < 0)
diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
index 1dc7e54ec32a..38227e670a83 100644
--- a/include/linux/pagemap.h
+++ b/include/linux/pagemap.h
@@ -365,7 +365,8 @@ static inline unsigned find_get_pages_tag(struct address_space *mapping,
 	return find_get_pages_range_tag(mapping, index, (pgoff_t)-1, tag,
 					nr_pages, pages);
 }
-unsigned find_get_entries_tag(struct address_space *mapping, pgoff_t *start,
+unsigned find_get_entries_range_tag(struct address_space *mapping,
+			pgoff_t *start, pgoff_t end,
 			int tag, unsigned int nr_entries,
 			struct page **entries, pgoff_t *indices);
 
diff --git a/mm/filemap.c b/mm/filemap.c
index 3eb05c91c07a..06f82ed9096e 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -1720,9 +1720,10 @@ unsigned find_get_pages_range_tag(struct address_space *mapping, pgoff_t *index,
 EXPORT_SYMBOL(find_get_pages_range_tag);
 
 /**
- * find_get_entries_tag - find and return entries that match @tag
+ * find_get_entries_range_tag - find and return entries that match @tag
  * @mapping:	the address_space to search
  * @start:	the starting page cache index
+ * @end:	the final page cache index (inclusive)
  * @tag:	the tag index
  * @nr_entries:	the maximum number of entries
  * @entries:	where the resulting entries are placed
@@ -1731,9 +1732,10 @@ EXPORT_SYMBOL(find_get_pages_range_tag);
  * Like find_get_entries, except we only return entries which are tagged with
  * @tag.
  */
-unsigned find_get_entries_tag(struct address_space *mapping, pgoff_t *start,
-			int tag, unsigned int nr_entries,
-			struct page **entries, pgoff_t *indices)
+unsigned find_get_entries_range_tag(struct address_space *mapping,
+			pgoff_t *start, pgoff_t end, int tag,
+			unsigned int nr_entries, struct page **entries,
+			pgoff_t *indices)
 {
 	void **slot;
 	unsigned int ret = 0;
@@ -1746,6 +1748,9 @@ unsigned find_get_entries_tag(struct address_space *mapping, pgoff_t *start,
 	radix_tree_for_each_tagged(slot, &mapping->page_tree,
 				   &iter, *start, tag) {
 		struct page *head, *page;
+
+		if (iter.index > end)
+			break;
 repeat:
 		page = radix_tree_deref_slot(slot);
 		if (unlikely(!page))
@@ -1782,17 +1787,28 @@ unsigned find_get_entries_tag(struct address_space *mapping, pgoff_t *start,
 export:
 		indices[ret] = iter.index;
 		entries[ret] = page;
-		if (++ret == nr_entries)
-			break;
+		if (++ret == nr_entries) {
+			*start = indices[ret - 1] + 1;
+			goto out;
+		}
 	}
-	rcu_read_unlock();
 
-	if (ret)
-		*start = indices[ret - 1] + 1;
+	/*
+	 * We come here when we got at @end. We take care to not overflow the
+	 * index @index as it confuses some of the callers. This breaks the
+	 * iteration when there is page at index -1 but that is already broken
+	 * anyway.
+	 */
+	if (end == (pgoff_t)-1)
+		*start = (pgoff_t)-1;
+	else
+		*start = end + 1;
+out:
+	rcu_read_unlock();
 
 	return ret;
 }
-EXPORT_SYMBOL(find_get_entries_tag);
+EXPORT_SYMBOL(find_get_entries_range_tag);
 
 /*
  * CD/DVDs are error prone. When a medium error occurs, the driver may fail
-- 
2.12.3

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related	[flat|nested] 43+ messages in thread

* Re: [PATCH 01/35] fscache: Remove unused ->now_uncached callback
  2017-06-01  9:32 [PATCH 00/35 v1] pagevec API cleanups Jan Kara
                   ` (34 preceding siblings ...)
  2017-06-01  9:32 ` [PATCH 35/35] mm: Implement find_get_entries_range_tag() Jan Kara
@ 2017-06-01 10:26 ` David Howells
  2017-06-01 11:34   ` Jan Kara
  2017-06-01 11:36 ` [Cluster-devel] [PATCH 00/35 v1] pagevec API cleanups Christoph Hellwig
  36 siblings, 1 reply; 43+ messages in thread
From: David Howells @ 2017-06-01 10:26 UTC (permalink / raw)
  To: Jan Kara
  Cc: dhowells, linux-mm, Hugh Dickins, linux-afs, Ryusuke Konishi,
	linux-nilfs, Bob Peterson, cluster-devel, Jaegeuk Kim,
	linux-f2fs-devel, tytso, linux-ext4, Ilya Dryomov, Yan, Zheng,
	ceph-devel, linux-btrfs, David Sterba, Darrick J . Wong,
	linux-xfs, Nadia Yvette Chambers

Jan Kara <jack@suse.cz> wrote:

> The callback doesn't ever get called. Remove it.

Hmmm...  I should perhaps be calling this.  I'm not sure why I never did.

At the moment, it doesn't strictly matter as ops on pages marked with
PG_fscache get ignored if the cache has suffered an I/O error or has been
withdrawn - but it will incur a performance penalty (the PG_fscache flag is
checked in the netfs before calling into fscache).

The downside of calling this is that when a cache is removed, fscache would go
through all the cookies for that cache and iterate over all the pages
associated with those cookies - which could cause a performance dip in the
system.

David

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH 01/35] fscache: Remove unused ->now_uncached callback
  2017-06-01 10:26 ` [PATCH 01/35] fscache: Remove unused ->now_uncached callback David Howells
@ 2017-06-01 11:34   ` Jan Kara
  2017-06-19 13:12     ` Jan Kara
  0 siblings, 1 reply; 43+ messages in thread
From: Jan Kara @ 2017-06-01 11:34 UTC (permalink / raw)
  To: David Howells
  Cc: Jan Kara, linux-mm, Hugh Dickins, linux-afs, Ryusuke Konishi,
	linux-nilfs, Bob Peterson, cluster-devel, Jaegeuk Kim,
	linux-f2fs-devel, tytso, linux-ext4, Ilya Dryomov, Yan, Zheng,
	ceph-devel, linux-btrfs, David Sterba, Darrick J . Wong,
	linux-xfs, Nadia Yvette Chambers

On Thu 01-06-17 11:26:08, David Howells wrote:
> Jan Kara <jack@suse.cz> wrote:
> 
> > The callback doesn't ever get called. Remove it.
> 
> Hmmm...  I should perhaps be calling this.  I'm not sure why I never did.
> 
> At the moment, it doesn't strictly matter as ops on pages marked with
> PG_fscache get ignored if the cache has suffered an I/O error or has been
> withdrawn - but it will incur a performance penalty (the PG_fscache flag is
> checked in the netfs before calling into fscache).
> 
> The downside of calling this is that when a cache is removed, fscache would go
> through all the cookies for that cache and iterate over all the pages
> associated with those cookies - which could cause a performance dip in the
> system.

So I know nothing about fscache. If you decide these functions should stay
in as you are going to use them soon, then I can just convert them to the
new API as everything else. What just caught my eye and why I had a more
detailed look is that I didn't understand that 'PAGEVEC_SIZE -
pagevec_count(&pvec)' as a pagevec_lookup() argument since pagevec_count()
should always return 0 at that point?

								Honza
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [Cluster-devel] [PATCH 00/35 v1] pagevec API cleanups
  2017-06-01  9:32 [PATCH 00/35 v1] pagevec API cleanups Jan Kara
                   ` (35 preceding siblings ...)
  2017-06-01 10:26 ` [PATCH 01/35] fscache: Remove unused ->now_uncached callback David Howells
@ 2017-06-01 11:36 ` Christoph Hellwig
  2017-06-01 12:05   ` Jan Kara
  36 siblings, 1 reply; 43+ messages in thread
From: Christoph Hellwig @ 2017-06-01 11:36 UTC (permalink / raw)
  To: Jan Kara
  Cc: linux-mm, cluster-devel, linux-nilfs, tytso, linux-xfs, Yan,
	Zheng, Darrick J . Wong, Hugh Dickins, linux-f2fs-devel,
	David Howells, David Sterba, ceph-devel, Nadia Yvette Chambers,
	Ryusuke Konishi, Jaegeuk Kim, Ilya Dryomov, linux-ext4,
	linux-afs, linux-btrfs

On Thu, Jun 01, 2017 at 11:32:10AM +0200, Jan Kara wrote:
> * Implement ranged variants for pagevec_lookup and find_get_ functions. Lot
>   of callers actually want a ranged lookup and we unnecessarily opencode this
>   in lot of them.

How does this compare to Kents page cache iterators:

http://www.spinics.net/lists/linux-mm/msg104737.html

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [Cluster-devel] [PATCH 00/35 v1] pagevec API cleanups
  2017-06-01 11:36 ` [Cluster-devel] [PATCH 00/35 v1] pagevec API cleanups Christoph Hellwig
@ 2017-06-01 12:05   ` Jan Kara
  0 siblings, 0 replies; 43+ messages in thread
From: Jan Kara @ 2017-06-01 12:05 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Jan Kara, linux-mm, cluster-devel, linux-nilfs, tytso, linux-xfs,
	Yan, Zheng, Darrick J . Wong, Hugh Dickins, linux-f2fs-devel,
	David Howells, David Sterba, ceph-devel, Nadia Yvette Chambers,
	Ryusuke Konishi, Jaegeuk Kim, Ilya Dryomov, linux-ext4,
	linux-afs, linux-btrfs

On Thu 01-06-17 04:36:04, Christoph Hellwig wrote:
> On Thu, Jun 01, 2017 at 11:32:10AM +0200, Jan Kara wrote:
> > * Implement ranged variants for pagevec_lookup and find_get_ functions. Lot
> >   of callers actually want a ranged lookup and we unnecessarily opencode this
> >   in lot of them.
> 
> How does this compare to Kents page cache iterators:
> 
> http://www.spinics.net/lists/linux-mm/msg104737.html

Interesting. I didn't know about that work. I guess the tradeoff is pretty
obvious - my patches are more conservative (changing less) and as a result
the API is not as neat as Kent's one. That being said I was also thinking
about something similar to what Kent did but what I didn't like about such
iterator is that you still need to specially handle the cases where you
break out of the loop (you need to do that with pagevecs too but there it
is kind of obvious from the API).

								Honza
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH 19/35] f2fs: Simplify page iteration loops
  2017-06-01  9:32 ` [PATCH 19/35] f2fs: Simplify page iteration loops Jan Kara
@ 2017-06-01 13:00   ` kbuild test robot
  0 siblings, 0 replies; 43+ messages in thread
From: kbuild test robot @ 2017-06-01 13:00 UTC (permalink / raw)
  To: Jan Kara
  Cc: kbuild-all, linux-mm, Hugh Dickins, David Howells, linux-afs,
	Ryusuke Konishi, linux-nilfs, Bob Peterson, cluster-devel,
	Jaegeuk Kim, linux-f2fs-devel, tytso, linux-ext4, Ilya Dryomov,
	Yan, Zheng, ceph-devel, linux-btrfs, David Sterba,
	Darrick J . Wong, linux-xfs, Nadia Yvette Chambers

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

Hi Jan,

[auto build test WARNING on linus/master]
[also build test WARNING on v4.12-rc3]
[cannot apply to next-20170601]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Jan-Kara/pagevec-API-cleanups/20170601-200653
config: x86_64-randconfig-x019-201722 (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All warnings (new ones prefixed by >>):

   fs//f2fs/checkpoint.c: In function 'sync_meta_pages':
>> fs//f2fs/checkpoint.c:313:5: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
        PAGECACHE_TAG_DIRTY, PAGEVEC_SIZE)) {
        ^~~~~~~~~~~~~~~~~~~
--
   fs//f2fs/node.c: In function 'last_fsync_dnode':
>> fs//f2fs/node.c:1271:5: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
        PAGECACHE_TAG_DIRTY, PAGEVEC_SIZE)) {
        ^~~~~~~~~~~~~~~~~~~
   fs//f2fs/node.c: In function 'fsync_node_pages':
   fs//f2fs/node.c:1421:5: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
        PAGECACHE_TAG_DIRTY, PAGEVEC_SIZE)) {
        ^~~~~~~~~~~~~~~~~~~
   fs//f2fs/node.c: In function 'sync_node_pages':
   fs//f2fs/node.c:1533:5: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
        PAGECACHE_TAG_DIRTY, PAGEVEC_SIZE)) {
        ^~~~~~~~~~~~~~~~~~~
   fs//f2fs/node.c: In function 'wait_on_node_pages_writeback':
   fs//f2fs/node.c:1630:5: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
        PAGECACHE_TAG_WRITEBACK, PAGEVEC_SIZE)) {
        ^~~~~~~~~~~~~~~~~~~~~~~

vim +313 fs//f2fs/checkpoint.c

   297	{
   298		struct address_space *mapping = META_MAPPING(sbi);
   299		pgoff_t index = 0, prev = ULONG_MAX;
   300		struct pagevec pvec;
   301		long nwritten = 0;
   302		int nr_pages;
   303		struct writeback_control wbc = {
   304			.for_reclaim = 0,
   305		};
   306		struct blk_plug plug;
   307	
   308		pagevec_init(&pvec, 0);
   309	
   310		blk_start_plug(&plug);
   311	
   312		while (nr_pages = pagevec_lookup_tag(&pvec, mapping, &index,
 > 313					PAGECACHE_TAG_DIRTY, PAGEVEC_SIZE)) {
   314			int i;
   315	
   316			for (i = 0; i < nr_pages; i++) {
   317				struct page *page = pvec.pages[i];
   318	
   319				if (prev == ULONG_MAX)
   320					prev = page->index - 1;
   321				if (nr_to_write != LONG_MAX && page->index != prev + 1) {

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 23456 bytes --]

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH 31/35] shmem: Convert to pagevec_lookup_entries_range()
  2017-06-01  9:32 ` [PATCH 31/35] shmem: Convert to pagevec_lookup_entries_range() Jan Kara
@ 2017-06-01 13:55   ` kbuild test robot
  0 siblings, 0 replies; 43+ messages in thread
From: kbuild test robot @ 2017-06-01 13:55 UTC (permalink / raw)
  To: Jan Kara
  Cc: kbuild-all, linux-mm, Hugh Dickins, David Howells, linux-afs,
	Ryusuke Konishi, linux-nilfs, Bob Peterson, cluster-devel,
	Jaegeuk Kim, linux-f2fs-devel, tytso, linux-ext4, Ilya Dryomov,
	Yan, Zheng, ceph-devel, linux-btrfs, David Sterba,
	Darrick J . Wong, linux-xfs, Nadia Yvette Chambers

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

Hi Jan,

[auto build test WARNING on linus/master]
[also build test WARNING on v4.12-rc3]
[cannot apply to next-20170601]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Jan-Kara/pagevec-API-cleanups/20170601-200653
config: i386-randconfig-x078-06010927 (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

Note: it may well be a FALSE warning. FWIW you are at least aware of it now.
http://gcc.gnu.org/wiki/Better_Uninitialized_Warnings

All warnings (new ones prefixed by >>):

   Cyclomatic Complexity 1 include/linux/huge_mm.h:split_huge_page
   Cyclomatic Complexity 1 include/linux/radix-tree.h:radix_tree_insert
   Cyclomatic Complexity 10 mm/shmem.c:shmem_add_to_page_cache
   Cyclomatic Complexity 2 include/linux/highmem.h:clear_highpage
   Cyclomatic Complexity 1 mm/shmem.c:shmem_confirm_swap
   Cyclomatic Complexity 2 include/linux/mm.h:put_page
   Cyclomatic Complexity 7 mm/shmem.c:shmem_write_end
   Cyclomatic Complexity 4 mm/shmem.c:shmem_replace_page
   Cyclomatic Complexity 13 mm/shmem.c:shmem_unused_huge_shrink
   Cyclomatic Complexity 69 mm/shmem.c:shmem_getpage_gfp
   Cyclomatic Complexity 2 mm/shmem.c:shmem_unused_huge_scan
   Cyclomatic Complexity 1 mm/shmem.c:shmem_put_link
   Cyclomatic Complexity 11 mm/shmem.c:shmem_fault
   Cyclomatic Complexity 1 mm/shmem.c:synchronous_wake_function
   Cyclomatic Complexity 1 include/linux/sched.h:cond_resched_rcu
   Cyclomatic Complexity 5 mm/shmem.c:find_swap_entry
   Cyclomatic Complexity 2 include/linux/pagemap.h:linear_page_index
   Cyclomatic Complexity 2 include/linux/pagevec.h:pagevec_release
   Cyclomatic Complexity 1 include/linux/pagevec.h:pagevec_lookup
   Cyclomatic Complexity 2 include/linux/pagemap.h:page_to_pgoff
   Cyclomatic Complexity 2 mm/shmem.c:shmem_free_swap
   Cyclomatic Complexity 8 mm/shmem.c:shmem_unuse_inode
   Cyclomatic Complexity 1 include/linux/fs.h:inode_lock
   Cyclomatic Complexity 1 include/linux/fs.h:inode_unlock
   Cyclomatic Complexity 2 include/linux/fs.h:file_accessed
   Cyclomatic Complexity 7 include/linux/khugepaged.h:khugepaged_enter
   Cyclomatic Complexity 2 mm/shmem.c:shmem_mmap
   Cyclomatic Complexity 12 mm/shmem.c:shmem_seek_hole_data
   Cyclomatic Complexity 8 mm/shmem.c:shmem_file_llseek
   Cyclomatic Complexity 2 include/linux/uaccess.h:copy_user_overflow
   Cyclomatic Complexity 2 include/linux/mm.h:page_mapcount
   Cyclomatic Complexity 8 mm/shmem.c:shmem_tag_pins
   Cyclomatic Complexity 13 mm/shmem.c:shmem_wait_for_pins
   Cyclomatic Complexity 2 include/linux/xattr.h:simple_xattrs_free
   Cyclomatic Complexity 1 include/linux/xattr.h:simple_xattrs_init
   Cyclomatic Complexity 7 mm/shmem.c:shmem_show_options
   Cyclomatic Complexity 1 include/linux/percpu_counter.h:percpu_counter_sum
   Cyclomatic Complexity 3 mm/shmem.c:shmem_statfs
   Cyclomatic Complexity 2 mm/shmem.c:shmem_destroy_inode
   Cyclomatic Complexity 2 mm/shmem.c:shmem_destroy_callback
   Cyclomatic Complexity 2 mm/shmem.c:shmem_alloc_inode
   Cyclomatic Complexity 3 mm/shmem.c:shmem_fh_to_dentry
   Cyclomatic Complexity 4 mm/shmem.c:shmem_encode_fh
   Cyclomatic Complexity 7 mm/shmem.c:shmem_parse_huge
   Cyclomatic Complexity 8 mm/shmem.c:shmem_enabled_store
   Cyclomatic Complexity 94 mm/shmem.c:shmem_parse_options
   Cyclomatic Complexity 9 mm/shmem.c:shmem_remount_fs
   Cyclomatic Complexity 6 mm/shmem.c:shmem_get_inode
   Cyclomatic Complexity 4 mm/shmem.c:shmem_tmpfile
   Cyclomatic Complexity 3 mm/shmem.c:shmem_exchange
   Cyclomatic Complexity 3 mm/shmem.c:shmem_unlink
   Cyclomatic Complexity 2 mm/shmem.c:shmem_rmdir
   Cyclomatic Complexity 2 include/linux/dcache.h:dget
   Cyclomatic Complexity 4 mm/shmem.c:shmem_mknod
   Cyclomatic Complexity 3 mm/shmem.c:shmem_whiteout
   Cyclomatic Complexity 9 mm/shmem.c:shmem_rename2
   Cyclomatic Complexity 2 mm/shmem.c:shmem_mkdir
   Cyclomatic Complexity 1 mm/shmem.c:shmem_create
   Cyclomatic Complexity 2 mm/shmem.c:shmem_link
   Cyclomatic Complexity 2 mm/shmem.c:shmem_getattr
   Cyclomatic Complexity 1 mm/shmem.c:shmem_put_super
   Cyclomatic Complexity 7 mm/shmem.c:shmem_fill_super
   Cyclomatic Complexity 1 mm/shmem.c:shmem_mount
   Cyclomatic Complexity 1 mm/shmem.c:shmem_init_inodecache
   Cyclomatic Complexity 1 mm/shmem.c:shmem_init_inode
   Cyclomatic Complexity 1 mm/shmem.c:shmem_destroy_inodecache
   Cyclomatic Complexity 3 mm/shmem.c:shmem_enabled_show
   Cyclomatic Complexity 8 mm/shmem.c:__shmem_file_setup
   Cyclomatic Complexity 1 mm/shmem.c:shmem_getpage
   Cyclomatic Complexity 5 mm/shmem.c:shmem_write_begin
   Cyclomatic Complexity 36 mm/shmem.c:shmem_undo_range
   Cyclomatic Complexity 17 mm/shmem.c:shmem_file_read_iter
   Cyclomatic Complexity 8 mm/shmem.c:shmem_symlink
   Cyclomatic Complexity 5 mm/shmem.c:shmem_get_link
   Cyclomatic Complexity 1 mm/shmem.c:vma_is_shmem
   Cyclomatic Complexity 4 mm/shmem.c:shmem_charge
   Cyclomatic Complexity 2 mm/shmem.c:shmem_uncharge
   Cyclomatic Complexity 7 mm/shmem.c:shmem_partial_swap_usage
   Cyclomatic Complexity 4 mm/shmem.c:shmem_swap_usage
   Cyclomatic Complexity 3 mm/shmem.c:shmem_unlock_mapping
   Cyclomatic Complexity 1 mm/shmem.c:shmem_truncate_range
   Cyclomatic Complexity 19 mm/shmem.c:shmem_fallocate
   Cyclomatic Complexity 6 mm/shmem.c:shmem_evict_inode
   Cyclomatic Complexity 16 mm/shmem.c:shmem_setattr
   Cyclomatic Complexity 9 mm/shmem.c:shmem_unuse
   Cyclomatic Complexity 7 mm/shmem.c:shmem_lock
   Cyclomatic Complexity 1 mm/shmem.c:shmem_mapping
   Cyclomatic Complexity 16 mm/shmem.c:shmem_mcopy_atomic_pte
   Cyclomatic Complexity 9 mm/shmem.c:shmem_add_seals
   Cyclomatic Complexity 2 mm/shmem.c:shmem_get_seals
   Cyclomatic Complexity 3 mm/shmem.c:shmem_fcntl
   Cyclomatic Complexity 7 mm/shmem.c:shmem_init
   Cyclomatic Complexity 8 mm/shmem.c:shmem_huge_enabled
   Cyclomatic Complexity 1 mm/shmem.c:shmem_kernel_file_setup
   Cyclomatic Complexity 1 mm/shmem.c:shmem_file_setup
   Cyclomatic Complexity 11 mm/shmem.c:SYSC_memfd_create
   Cyclomatic Complexity 1 mm/shmem.c:SyS_memfd_create
   Cyclomatic Complexity 4 mm/shmem.c:shmem_zero_setup
   Cyclomatic Complexity 2 mm/shmem.c:shmem_read_mapping_page_gfp
   mm/shmem.c: In function 'shmem_seek_hole_data':
>> mm/shmem.c:2522:9: warning: 'last' may be used uninitialized in this function [-Wmaybe-uninitialized]
     return last;
            ^~~~

vim +/last +2522 mm/shmem.c

220f2ac9 Hugh Dickins    2012-12-12  2506  			page = pvec.pages[i];
220f2ac9 Hugh Dickins    2012-12-12  2507  			if (page && !radix_tree_exceptional_entry(page)) {
220f2ac9 Hugh Dickins    2012-12-12  2508  				if (!PageUptodate(page))
220f2ac9 Hugh Dickins    2012-12-12  2509  					page = NULL;
220f2ac9 Hugh Dickins    2012-12-12  2510  			}
eb675e81 Jan Kara        2017-06-01  2511  			if ((page && whence == SEEK_DATA) ||
965c8e59 Andrew Morton   2012-12-17  2512  			    (!page && whence == SEEK_HOLE)) {
220f2ac9 Hugh Dickins    2012-12-12  2513  				done = true;
220f2ac9 Hugh Dickins    2012-12-12  2514  				break;
220f2ac9 Hugh Dickins    2012-12-12  2515  			}
220f2ac9 Hugh Dickins    2012-12-12  2516  		}
0cd6144a Johannes Weiner 2014-04-03  2517  		pagevec_remove_exceptionals(&pvec);
220f2ac9 Hugh Dickins    2012-12-12  2518  		pagevec_release(&pvec);
220f2ac9 Hugh Dickins    2012-12-12  2519  		pvec.nr = PAGEVEC_SIZE;
220f2ac9 Hugh Dickins    2012-12-12  2520  		cond_resched();
220f2ac9 Hugh Dickins    2012-12-12  2521  	}
1d162ad5 Jan Kara        2017-06-01 @2522  	return last;
220f2ac9 Hugh Dickins    2012-12-12  2523  }
220f2ac9 Hugh Dickins    2012-12-12  2524  
965c8e59 Andrew Morton   2012-12-17  2525  static loff_t shmem_file_llseek(struct file *file, loff_t offset, int whence)
220f2ac9 Hugh Dickins    2012-12-12  2526  {
220f2ac9 Hugh Dickins    2012-12-12  2527  	struct address_space *mapping = file->f_mapping;
220f2ac9 Hugh Dickins    2012-12-12  2528  	struct inode *inode = mapping->host;
220f2ac9 Hugh Dickins    2012-12-12  2529  	pgoff_t start, end;
220f2ac9 Hugh Dickins    2012-12-12  2530  	loff_t new_offset;

:::::: The code at line 2522 was first introduced by commit
:::::: 1d162ad5252576fa97d38e96e6e09fd9165f5d6b mm: Make pagevec_lookup_entries() update index

:::::: TO: Jan Kara <jack@suse.cz>
:::::: CC: 0day robot <fengguang.wu@intel.com>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 26845 bytes --]

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH 01/35] fscache: Remove unused ->now_uncached callback
  2017-06-01 11:34   ` Jan Kara
@ 2017-06-19 13:12     ` Jan Kara
  0 siblings, 0 replies; 43+ messages in thread
From: Jan Kara @ 2017-06-19 13:12 UTC (permalink / raw)
  To: David Howells
  Cc: Jan Kara, linux-mm, Hugh Dickins, linux-afs, Ryusuke Konishi,
	linux-nilfs, Bob Peterson, cluster-devel, Jaegeuk Kim,
	linux-f2fs-devel, tytso, linux-ext4, Ilya Dryomov, Yan, Zheng,
	ceph-devel, linux-btrfs, David Sterba, Darrick J . Wong,
	linux-xfs, Nadia Yvette Chambers

On Thu 01-06-17 13:34:34, Jan Kara wrote:
> On Thu 01-06-17 11:26:08, David Howells wrote:
> > Jan Kara <jack@suse.cz> wrote:
> > 
> > > The callback doesn't ever get called. Remove it.
> > 
> > Hmmm...  I should perhaps be calling this.  I'm not sure why I never did.
> > 
> > At the moment, it doesn't strictly matter as ops on pages marked with
> > PG_fscache get ignored if the cache has suffered an I/O error or has been
> > withdrawn - but it will incur a performance penalty (the PG_fscache flag is
> > checked in the netfs before calling into fscache).
> > 
> > The downside of calling this is that when a cache is removed, fscache would go
> > through all the cookies for that cache and iterate over all the pages
> > associated with those cookies - which could cause a performance dip in the
> > system.
> 
> So I know nothing about fscache. If you decide these functions should stay
> in as you are going to use them soon, then I can just convert them to the
> new API as everything else. What just caught my eye and why I had a more
> detailed look is that I didn't understand that 'PAGEVEC_SIZE -
> pagevec_count(&pvec)' as a pagevec_lookup() argument since pagevec_count()
> should always return 0 at that point?

David, what is your final decision regarding this? Do you want to keep
these unused functions (and I will just update my patch to convert them to
the new calling convention) or will you apply the patch to remove them?

								Honza
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 43+ messages in thread

end of thread, other threads:[~2017-06-19 13:12 UTC | newest]

Thread overview: 43+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-06-01  9:32 [PATCH 00/35 v1] pagevec API cleanups Jan Kara
2017-06-01  9:32 ` [PATCH 01/35] fscache: Remove unused ->now_uncached callback Jan Kara
2017-06-01  9:32 ` [PATCH 02/35] ext4: Fix SEEK_HOLE Jan Kara
2017-06-01  9:32 ` [PATCH 03/35] ext4: Fix off-by-in in loop termination in ext4_find_unwritten_pgoff() Jan Kara
2017-06-01  9:32 ` [PATCH 04/35] dax: Fix inefficiency in dax_writeback_mapping_range() Jan Kara
2017-06-01  9:32 ` [PATCH 05/35] mm: Fix THP handling in invalidate_mapping_pages() Jan Kara
2017-06-01  9:32 ` [PATCH 06/35] mm: Make pagevec_lookup() update index Jan Kara
2017-06-01  9:32 ` [PATCH 07/35] mm: Implement find_get_pages_range() Jan Kara
2017-06-01  9:32 ` [PATCH 08/35] fs: Fix performance regression in clean_bdev_aliases() Jan Kara
2017-06-01  9:32 ` [PATCH 09/35] ext4: Use pagevec_lookup_range() in ext4_find_unwritten_pgoff() Jan Kara
2017-06-01  9:32 ` [PATCH 10/35] ext4: Use pagevec_lookup_range() in writeback code Jan Kara
2017-06-01  9:32 ` [PATCH 11/35] hugetlbfs: Use pagevec_lookup_range() in remove_inode_hugepages() Jan Kara
2017-06-01  9:32 ` [PATCH 12/35] xfs: Use pagevec_lookup_range() in xfs_find_get_desired_pgoff() Jan Kara
2017-06-01  9:32 ` [PATCH 13/35] mm: Remove nr_pages argument from pagevec_lookup{,_range}() Jan Kara
2017-06-01  9:32 ` [PATCH 14/35] mm: Implement find_get_pages_range_tag() Jan Kara
2017-06-01  9:32 ` [PATCH 15/35] btrfs: Use pagevec_lookup_range_tag() Jan Kara
2017-06-01  9:32 ` [PATCH 16/35] ceph: " Jan Kara
2017-06-01  9:32 ` [PATCH 17/35] ext4: " Jan Kara
2017-06-01  9:32 ` [PATCH 18/35] f2fs: " Jan Kara
2017-06-01  9:32 ` [PATCH 19/35] f2fs: Simplify page iteration loops Jan Kara
2017-06-01 13:00   ` kbuild test robot
2017-06-01  9:32 ` [PATCH 20/35] f2fs: Use find_get_pages_tag() for looking up single page Jan Kara
2017-06-01  9:32 ` [PATCH 21/35] gfs2: Use pagevec_lookup_range_tag() Jan Kara
2017-06-01  9:32 ` [PATCH 22/35] nilfs2: " Jan Kara
2017-06-01  9:32 ` [PATCH 23/35] mm: Use pagevec_lookup_range_tag() in __filemap_fdatawait_range() Jan Kara
2017-06-01  9:32 ` [PATCH 24/35] mm: Use pagevec_lookup_range_tag() in write_cache_pages() Jan Kara
2017-06-01  9:32 ` [PATCH 25/35] mm: Remove nr_pages argument from pagevec_lookup_{,range}_tag() Jan Kara
2017-06-01  9:32 ` [PATCH 26/35] afs: Use find_get_pages_range_tag() Jan Kara
2017-06-01  9:32 ` [PATCH 27/35] shmem: Use pagevec_lookup() in shmem_unlock_mapping() Jan Kara
2017-06-01  9:32 ` [PATCH 28/35] shmem: Use pagevec_lookup_entries() Jan Kara
2017-06-01  9:32 ` [PATCH 29/35] mm: Make pagevec_lookup_entries() update index Jan Kara
2017-06-01  9:32 ` [PATCH 30/35] mm: Implement find_get_entries_range() Jan Kara
2017-06-01  9:32 ` [PATCH 31/35] shmem: Convert to pagevec_lookup_entries_range() Jan Kara
2017-06-01 13:55   ` kbuild test robot
2017-06-01  9:32 ` [PATCH 32/35] mm: Convert truncate code " Jan Kara
2017-06-01  9:32 ` [PATCH 33/35] mm: Remove nr_entries argument from pagevec_lookup_entries{,_range}() Jan Kara
2017-06-01  9:32 ` [PATCH 34/35] mm: Make find_get_entries_tag() update index Jan Kara
2017-06-01  9:32 ` [PATCH 35/35] mm: Implement find_get_entries_range_tag() Jan Kara
2017-06-01 10:26 ` [PATCH 01/35] fscache: Remove unused ->now_uncached callback David Howells
2017-06-01 11:34   ` Jan Kara
2017-06-19 13:12     ` Jan Kara
2017-06-01 11:36 ` [Cluster-devel] [PATCH 00/35 v1] pagevec API cleanups Christoph Hellwig
2017-06-01 12:05   ` Jan Kara

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).