Home Home > GIT Browse
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnthony Iliopoulos <ailiopoulos@suse.com>2019-03-20 01:08:33 +0100
committerAnthony Iliopoulos <ailiopoulos@suse.com>2019-03-20 01:08:33 +0100
commit9de815a63c4aa747882525d63e0557172bc93f6c (patch)
tree8cbf0cefd082b290d3d804f3b54f39d16406d59d
parentb78c8624f20cf958ac577d5a992bfc5df6a5a79d (diff)
- xfs: Switch to iomap for SEEK_HOLE / SEEK_DATA (bsc#1070995).
- Refresh patches.suse/mm-pagevec-remove-cold-parameter-for-pagevecs.patch.
-rw-r--r--patches.fixes/xfs-Switch-to-iomap-for-SEEK_HOLE-SEEK_DATA.patch431
-rw-r--r--patches.suse/mm-pagevec-remove-cold-parameter-for-pagevecs.patch246
-rw-r--r--series.conf1
3 files changed, 517 insertions, 161 deletions
diff --git a/patches.fixes/xfs-Switch-to-iomap-for-SEEK_HOLE-SEEK_DATA.patch b/patches.fixes/xfs-Switch-to-iomap-for-SEEK_HOLE-SEEK_DATA.patch
new file mode 100644
index 0000000000..3946fd8160
--- /dev/null
+++ b/patches.fixes/xfs-Switch-to-iomap-for-SEEK_HOLE-SEEK_DATA.patch
@@ -0,0 +1,431 @@
+From 9b2970aacfd9aa5d9bad377a554a002b398f882e Mon Sep 17 00:00:00 2001
+From: Christoph Hellwig <hch@lst.de>
+Date: Thu, 29 Jun 2017 11:43:21 -0700
+Subject: [PATCH] xfs: Switch to iomap for SEEK_HOLE / SEEK_DATA
+Git-commit: 9b2970aacfd9aa5d9bad377a554a002b398f882e
+Patch-mainline: v4.13-rc1
+References: bsc#1070995
+
+Switch to the iomap_seek_hole and iomap_seek_data helpers for
+implementing lseek SEEK_HOLE / SEEK_DATA, and remove all the
+code that isn't needed any more.
+
+Based on patches from Andreas Gruenbacher <agruenba@redhat.com>.
+
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
+Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
+Acked-by: Anthony Iliopoulos <ailiopoulos@suse.com>
+
+---
+ fs/xfs/xfs_file.c | 375 +----------------------------------------------------
+ fs/xfs/xfs_inode.h | 3
+ 2 files changed, 14 insertions(+), 364 deletions(-)
+
+--- a/fs/xfs/xfs_file.c
++++ b/fs/xfs/xfs_file.c
+@@ -973,378 +973,31 @@
+ return xfs_readdir(ip, ctx, bufsize);
+ }
+
+-/*
+- * This type is designed to indicate the type of offset we would like
+- * to search from page cache for xfs_seek_hole_data().
+- */
+-enum {
+- HOLE_OFF = 0,
+- DATA_OFF,
+-};
+-
+-/*
+- * Lookup the desired type of offset from the given page.
+- *
+- * On success, return true and the offset argument will point to the
+- * start of the region that was found. Otherwise this function will
+- * return false and keep the offset argument unchanged.
+- */
+-STATIC bool
+-xfs_lookup_buffer_offset(
+- struct page *page,
+- loff_t *offset,
+- unsigned int type)
+-{
+- loff_t lastoff = page_offset(page);
+- bool found = false;
+- struct buffer_head *bh, *head;
+-
+- bh = head = page_buffers(page);
+- do {
+- /*
+- * Unwritten extents that have data in the page
+- * cache covering them can be identified by the
+- * BH_Unwritten state flag. Pages with multiple
+- * buffers might have a mix of holes, data and
+- * unwritten extents - any buffer with valid
+- * data in it should have BH_Uptodate flag set
+- * on it.
+- */
+- if (buffer_unwritten(bh) ||
+- buffer_uptodate(bh)) {
+- if (type == DATA_OFF)
+- found = true;
+- } else {
+- if (type == HOLE_OFF)
+- found = true;
+- }
+-
+- if (found) {
+- *offset = lastoff;
+- break;
+- }
+- lastoff += bh->b_size;
+- } while ((bh = bh->b_this_page) != head);
+-
+- return found;
+-}
+-
+-/*
+- * This routine is called to find out and return a data or hole offset
+- * from the page cache for unwritten extents according to the desired
+- * type for xfs_seek_hole_data().
+- *
+- * The argument offset is used to tell where we start to search from the
+- * page cache. Map is used to figure out the end points of the range to
+- * lookup pages.
+- *
+- * Return true if the desired type of offset was found, and the argument
+- * offset is filled with that address. Otherwise, return false and keep
+- * offset unchanged.
+- */
+-STATIC bool
+-xfs_find_get_desired_pgoff(
+- struct inode *inode,
+- struct xfs_bmbt_irec *map,
+- unsigned int type,
+- loff_t *offset)
+-{
+- struct xfs_inode *ip = XFS_I(inode);
+- struct xfs_mount *mp = ip->i_mount;
+- struct pagevec pvec;
+- pgoff_t index;
+- pgoff_t end;
+- loff_t endoff;
+- loff_t startoff = *offset;
+- loff_t lastoff = startoff;
+- bool found = false;
+-
+- pagevec_init(&pvec, 0);
+-
+- index = startoff >> PAGE_SHIFT;
+- 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);
+- if (nr_pages == 0)
+- break;
+-
+- for (i = 0; i < nr_pages; i++) {
+- struct page *page = pvec.pages[i];
+- loff_t b_offset;
+-
+- /*
+- * 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 current page offset is beyond where we've ended,
+- * we've found a hole.
+- */
+- if (type == HOLE_OFF && lastoff < endoff &&
+- lastoff < page_offset(pvec.pages[i])) {
+- found = true;
+- *offset = lastoff;
+- goto out;
+- }
+- /* Searching done if the page index is out of range. */
+- if (page->index > end)
+- goto out;
+-
+- lock_page(page);
+- /*
+- * Page truncated or invalidated(page->mapping == NULL).
+- * We can freely skip it and proceed to check the next
+- * page.
+- */
+- if (unlikely(page->mapping != inode->i_mapping)) {
+- unlock_page(page);
+- continue;
+- }
+-
+- if (!page_has_buffers(page)) {
+- unlock_page(page);
+- continue;
+- }
+-
+- found = xfs_lookup_buffer_offset(page, &b_offset, type);
+- if (found) {
+- /*
+- * The found offset may be less than the start
+- * point to search if this is the first time to
+- * come here.
+- */
+- *offset = max_t(loff_t, startoff, b_offset);
+- unlock_page(page);
+- goto out;
+- }
+-
+- /*
+- * We either searching data but nothing was found, or
+- * searching hole but found a data buffer. In either
+- * case, probably the next page contains the desired
+- * things, update the last offset to it so.
+- */
+- lastoff = page_offset(page) + PAGE_SIZE;
+- unlock_page(page);
+- }
+-
+- /*
+- * The number of returned pages less than our desired, search
+- * done.
+- */
+- if (nr_pages < want)
+- break;
+-
+- index = pvec.pages[i - 1]->index + 1;
+- pagevec_release(&pvec);
+- } while (index <= end);
+-
+- /* No page at lastoff and we are not done - we found a hole. */
+- if (type == HOLE_OFF && lastoff < endoff) {
+- *offset = lastoff;
+- found = true;
+- }
+-out:
+- pagevec_release(&pvec);
+- return found;
+-}
+-
+-/*
+- * caller must lock inode with xfs_ilock_data_map_shared,
+- * can we craft an appropriate ASSERT?
+- *
+- * end is because the VFS-level lseek interface is defined such that any
+- * offset past i_size shall return -ENXIO, but we use this for quota code
+- * which does not maintain i_size, and we want to SEEK_DATA past i_size.
+- */
+-loff_t
+-__xfs_seek_hole_data(
+- struct inode *inode,
+- loff_t start,
+- loff_t end,
+- int whence)
+-{
+- struct xfs_inode *ip = XFS_I(inode);
+- struct xfs_mount *mp = ip->i_mount;
+- loff_t uninitialized_var(offset);
+- xfs_fileoff_t fsbno;
+- xfs_filblks_t lastbno;
+- int error;
+-
+- if (start >= end) {
+- error = -ENXIO;
+- goto out_error;
+- }
+-
+- /*
+- * Try to read extents from the first block indicated
+- * by fsbno to the end block of the file.
+- */
+- fsbno = XFS_B_TO_FSBT(mp, start);
+- lastbno = XFS_B_TO_FSB(mp, end);
+-
+- for (;;) {
+- struct xfs_bmbt_irec map[2];
+- int nmap = 2;
+- unsigned int i;
+-
+- error = xfs_bmapi_read(ip, fsbno, lastbno - fsbno, map, &nmap,
+- XFS_BMAPI_ENTIRE);
+- if (error)
+- goto out_error;
+-
+- /* No extents at given offset, must be beyond EOF */
+- if (nmap == 0) {
+- error = -ENXIO;
+- goto out_error;
+- }
+-
+- for (i = 0; i < nmap; i++) {
+- offset = max_t(loff_t, start,
+- XFS_FSB_TO_B(mp, map[i].br_startoff));
+-
+- /* Landed in the hole we wanted? */
+- if (whence == SEEK_HOLE &&
+- map[i].br_startblock == HOLESTARTBLOCK)
+- goto out;
+-
+- /* Landed in the data extent we wanted? */
+- if (whence == SEEK_DATA &&
+- (map[i].br_startblock == DELAYSTARTBLOCK ||
+- (map[i].br_state == XFS_EXT_NORM &&
+- !isnullstartblock(map[i].br_startblock))))
+- goto out;
+-
+- /*
+- * Landed in an unwritten extent, try to search
+- * for hole or data from page cache.
+- */
+- if (map[i].br_state == XFS_EXT_UNWRITTEN) {
+- if (xfs_find_get_desired_pgoff(inode, &map[i],
+- whence == SEEK_HOLE ? HOLE_OFF : DATA_OFF,
+- &offset))
+- goto out;
+- }
+- }
+-
+- /*
+- * We only received one extent out of the two requested. This
+- * means we've hit EOF and didn't find what we are looking for.
+- */
+- if (nmap == 1) {
+- /*
+- * If we were looking for a hole, set offset to
+- * the end of the file (i.e., there is an implicit
+- * hole at the end of any file).
+- */
+- if (whence == SEEK_HOLE) {
+- offset = end;
+- break;
+- }
+- /*
+- * If we were looking for data, it's nowhere to be found
+- */
+- ASSERT(whence == SEEK_DATA);
+- error = -ENXIO;
+- goto out_error;
+- }
+-
+- ASSERT(i > 1);
+-
+- /*
+- * Nothing was found, proceed to the next round of search
+- * if the next reading offset is not at or beyond EOF.
+- */
+- fsbno = map[i - 1].br_startoff + map[i - 1].br_blockcount;
+- start = XFS_FSB_TO_B(mp, fsbno);
+- if (start >= end) {
+- if (whence == SEEK_HOLE) {
+- offset = end;
+- break;
+- }
+- ASSERT(whence == SEEK_DATA);
+- error = -ENXIO;
+- goto out_error;
+- }
+- }
+-
+-out:
+- /*
+- * If at this point we have found the hole we wanted, the returned
+- * offset may be bigger than the file size as it may be aligned to
+- * page boundary for unwritten extents. We need to deal with this
+- * situation in particular.
+- */
+- if (whence == SEEK_HOLE)
+- offset = min_t(loff_t, offset, end);
+-
+- return offset;
+-
+-out_error:
+- return error;
+-}
+-
+-STATIC loff_t
+-xfs_seek_hole_data(
+- struct file *file,
+- loff_t start,
+- int whence)
+-{
+- struct inode *inode = file->f_mapping->host;
+- struct xfs_inode *ip = XFS_I(inode);
+- struct xfs_mount *mp = ip->i_mount;
+- uint lock;
+- loff_t offset, end;
+- int error = 0;
+-
+- if (XFS_FORCED_SHUTDOWN(mp))
+- return -EIO;
+-
+- lock = xfs_ilock_data_map_shared(ip);
+-
+- end = i_size_read(inode);
+- offset = __xfs_seek_hole_data(inode, start, end, whence);
+- if (offset < 0) {
+- error = offset;
+- goto out_unlock;
+- }
+-
+- offset = vfs_setpos(file, offset, inode->i_sb->s_maxbytes);
+-
+-out_unlock:
+- xfs_iunlock(ip, lock);
+-
+- if (error)
+- return error;
+- return offset;
+-}
+-
+ STATIC loff_t
+ xfs_file_llseek(
+ struct file *file,
+ loff_t offset,
+ int whence)
+ {
++ struct inode *inode = file->f_mapping->host;
++
++ if (XFS_FORCED_SHUTDOWN(XFS_I(inode)->i_mount))
++ return -EIO;
++
+ switch (whence) {
+- case SEEK_END:
+- case SEEK_CUR:
+- case SEEK_SET:
++ default:
+ return generic_file_llseek(file, offset, whence);
+ case SEEK_HOLE:
++ offset = iomap_seek_hole(inode, offset, &xfs_iomap_ops);
++ break;
+ case SEEK_DATA:
+- return xfs_seek_hole_data(file, offset, whence);
+- default:
+- return -EINVAL;
++ offset = iomap_seek_data(inode, offset, &xfs_iomap_ops);
++ break;
+ }
++
++ if (offset < 0)
++ return offset;
++ return vfs_setpos(file, offset, inode->i_sb->s_maxbytes);
+ }
+
+ /*
+--- a/fs/xfs/xfs_inode.h
++++ b/fs/xfs/xfs_inode.h
+@@ -445,9 +445,6 @@
+ xfs_fsize_t isize, bool *did_zeroing);
+ int xfs_zero_range(struct xfs_inode *ip, xfs_off_t pos, xfs_off_t count,
+ bool *did_zero);
+-loff_t __xfs_seek_hole_data(struct inode *inode, loff_t start,
+- loff_t eof, int whence);
+-
+
+ /* from xfs_iops.c */
+ extern void xfs_setup_inode(struct xfs_inode *ip);
diff --git a/patches.suse/mm-pagevec-remove-cold-parameter-for-pagevecs.patch b/patches.suse/mm-pagevec-remove-cold-parameter-for-pagevecs.patch
index 9854976855..413732666c 100644
--- a/patches.suse/mm-pagevec-remove-cold-parameter-for-pagevecs.patch
+++ b/patches.suse/mm-pagevec-remove-cold-parameter-for-pagevecs.patch
@@ -26,45 +26,42 @@ Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Vlastimil Babka <vbabka@suse.cz>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---
- drivers/gpu/drm/i915/i915_gem_gtt.c | 2 +-
- fs/9p/cache.c | 2 +-
- fs/afs/cache.c | 2 +-
- fs/afs/write.c | 4 ++--
- fs/btrfs/extent_io.c | 4 ++--
- fs/buffer.c | 2 +-
- fs/cachefiles/rdwr.c | 4 ++--
- fs/ceph/addr.c | 4 ++--
- fs/ceph/cache.c | 2 +-
- fs/cifs/cache.c | 2 +-
- fs/dax.c | 2 +-
- fs/ext4/file.c | 2 +-
- fs/ext4/inode.c | 6 +++---
- fs/f2fs/checkpoint.c | 2 +-
- fs/f2fs/data.c | 2 +-
- fs/f2fs/file.c | 2 +-
- fs/f2fs/node.c | 8 ++++----
- fs/fscache/page.c | 2 +-
- fs/gfs2/aops.c | 2 +-
- fs/hugetlbfs/inode.c | 2 +-
- fs/nfs/fscache-index.c | 2 +-
- fs/nilfs2/btree.c | 2 +-
- fs/nilfs2/page.c | 8 ++++----
- fs/nilfs2/segment.c | 4 ++--
- fs/xfs/xfs_file.c | 2 +-
- include/linux/pagevec.h | 4 +---
- mm/filemap.c | 4 ++--
- mm/mlock.c | 4 ++--
- mm/page-writeback.c | 2 +-
- mm/shmem.c | 6 +++---
- mm/swap.c | 4 ++--
- mm/truncate.c | 8 ++++----
- 32 files changed, 53 insertions(+), 55 deletions(-)
+ drivers/gpu/drm/i915/i915_gem_gtt.c | 2 +-
+ fs/9p/cache.c | 2 +-
+ fs/afs/cache.c | 2 +-
+ fs/afs/write.c | 4 ++--
+ fs/btrfs/extent_io.c | 4 ++--
+ fs/buffer.c | 2 +-
+ fs/cachefiles/rdwr.c | 4 ++--
+ fs/ceph/addr.c | 4 ++--
+ fs/ceph/cache.c | 2 +-
+ fs/cifs/cache.c | 2 +-
+ fs/dax.c | 2 +-
+ fs/ext4/file.c | 2 +-
+ fs/ext4/inode.c | 6 +++---
+ fs/f2fs/checkpoint.c | 2 +-
+ fs/f2fs/data.c | 2 +-
+ fs/f2fs/file.c | 2 +-
+ fs/f2fs/node.c | 8 ++++----
+ fs/fscache/page.c | 2 +-
+ fs/gfs2/aops.c | 2 +-
+ fs/hugetlbfs/inode.c | 2 +-
+ fs/nfs/fscache-index.c | 2 +-
+ fs/nilfs2/btree.c | 2 +-
+ fs/nilfs2/page.c | 8 ++++----
+ fs/nilfs2/segment.c | 4 ++--
+ include/linux/pagevec.h | 4 +---
+ mm/filemap.c | 4 ++--
+ mm/mlock.c | 4 ++--
+ mm/page-writeback.c | 2 +-
+ mm/shmem.c | 6 +++---
+ mm/swap.c | 4 ++--
+ mm/truncate.c | 8 ++++----
+ 31 files changed, 52 insertions(+), 54 deletions(-)
-diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
-index a4c8d245c59f..6f1fd658d8c6 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
-@@ -1867,7 +1867,7 @@ static void i915_address_space_init(struct i915_address_space *vm,
+@@ -1859,7 +1859,7 @@
INIT_LIST_HEAD(&vm->unbound_list);
list_add_tail(&vm->global_link, &dev_priv->vm_list);
@@ -73,11 +70,9 @@ index a4c8d245c59f..6f1fd658d8c6 100644
}
static void i915_address_space_fini(struct i915_address_space *vm)
-diff --git a/fs/9p/cache.c b/fs/9p/cache.c
-index 103ca5e1267b..a4988040f7c0 100644
--- a/fs/9p/cache.c
+++ b/fs/9p/cache.c
-@@ -158,7 +158,7 @@ static void v9fs_cache_inode_now_uncached(void *cookie_netfs_data)
+@@ -158,7 +158,7 @@
pgoff_t first;
int loop, nr_pages;
@@ -86,11 +81,9 @@ index 103ca5e1267b..a4988040f7c0 100644
first = 0;
for (;;) {
-diff --git a/fs/afs/cache.c b/fs/afs/cache.c
-index 577763c3d88b..ae3fb3e752da 100644
--- a/fs/afs/cache.c
+++ b/fs/afs/cache.c
-@@ -377,7 +377,7 @@ static void afs_vnode_cache_now_uncached(void *cookie_netfs_data)
+@@ -377,7 +377,7 @@
_enter("{%x,%x,%Lx}",
vnode->fid.vnode, vnode->fid.unique, vnode->status.data_version);
@@ -99,11 +92,9 @@ index 577763c3d88b..ae3fb3e752da 100644
first = 0;
for (;;) {
-diff --git a/fs/afs/write.c b/fs/afs/write.c
-index 2d2fccd5044b..f63be7a06c43 100644
--- a/fs/afs/write.c
+++ b/fs/afs/write.c
-@@ -308,7 +308,7 @@ static void afs_kill_pages(struct afs_vnode *vnode, bool error,
+@@ -308,7 +308,7 @@
_enter("{%x:%u},%lx-%lx",
vnode->fid.vid, vnode->fid.vnode, first, last);
@@ -112,7 +103,7 @@ index 2d2fccd5044b..f63be7a06c43 100644
do {
_debug("kill %lx-%lx", first, last);
-@@ -609,7 +609,7 @@ void afs_pages_written_back(struct afs_vnode *vnode, struct afs_call *call)
+@@ -609,7 +609,7 @@
ASSERT(wb != NULL);
@@ -121,11 +112,9 @@ index 2d2fccd5044b..f63be7a06c43 100644
do {
_debug("done %lx-%lx", first, last);
-diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
-index a91042cd93ca..7c0b76e10a51 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
-@@ -3823,7 +3823,7 @@ int btree_write_cache_pages(struct address_space *mapping,
+@@ -3843,7 +3843,7 @@
int scanned = 0;
int tag;
@@ -134,7 +123,7 @@ index a91042cd93ca..7c0b76e10a51 100644
if (wbc->range_cyclic) {
index = mapping->writeback_index; /* Start from prev offset */
end = -1;
-@@ -3967,7 +3967,7 @@ static int extent_write_cache_pages(struct address_space *mapping,
+@@ -3987,7 +3987,7 @@
if (!igrab(inode))
return 0;
@@ -143,11 +132,9 @@ index a91042cd93ca..7c0b76e10a51 100644
if (wbc->range_cyclic) {
index = mapping->writeback_index; /* Start from prev offset */
end = -1;
-diff --git a/fs/buffer.c b/fs/buffer.c
-index 741cc9c9f640..0354a8d2ec1e 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
-@@ -1684,7 +1684,7 @@ void clean_bdev_aliases(struct block_device *bdev, sector_t block, sector_t len)
+@@ -1605,7 +1605,7 @@
struct buffer_head *head;
end = (block + len - 1) >> (PAGE_SHIFT - bd_inode->i_blkbits);
@@ -156,11 +143,9 @@ index 741cc9c9f640..0354a8d2ec1e 100644
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++) {
-diff --git a/fs/cachefiles/rdwr.c b/fs/cachefiles/rdwr.c
-index 18d7aa61ef0f..23097cca2674 100644
--- a/fs/cachefiles/rdwr.c
+++ b/fs/cachefiles/rdwr.c
-@@ -710,7 +710,7 @@ int cachefiles_read_or_alloc_pages(struct fscache_retrieval *op,
+@@ -710,7 +710,7 @@
/* calculate the shift required to use bmap */
shift = PAGE_SHIFT - inode->i_sb->s_blocksize_bits;
@@ -169,7 +154,7 @@ index 18d7aa61ef0f..23097cca2674 100644
op->op.flags &= FSCACHE_OP_KEEP_FLAGS;
op->op.flags |= FSCACHE_OP_ASYNC;
-@@ -844,7 +844,7 @@ int cachefiles_allocate_pages(struct fscache_retrieval *op,
+@@ -844,7 +844,7 @@
ret = cachefiles_has_space(cache, 0, *nr_pages);
if (ret == 0) {
@@ -178,11 +163,9 @@ index 18d7aa61ef0f..23097cca2674 100644
list_for_each_entry(page, pages, lru) {
if (pagevec_add(&pagevec, page) == 0)
-diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c
-index 8e03c9ae0bf0..43bef114a238 100644
--- a/fs/ceph/addr.c
+++ b/fs/ceph/addr.c
-@@ -644,7 +644,7 @@ static void ceph_release_pages(struct page **pages, int num)
+@@ -679,7 +679,7 @@
struct pagevec pvec;
int i;
@@ -191,7 +174,7 @@ index 8e03c9ae0bf0..43bef114a238 100644
for (i = 0; i < num; i++) {
if (pagevec_add(&pvec, pages[i]) == 0)
pagevec_release(&pvec);
-@@ -792,7 +792,7 @@ static int ceph_writepages_start(struct address_space *mapping,
+@@ -810,7 +810,7 @@
if (fsc->mount_options->wsize < wsize)
wsize = fsc->mount_options->wsize;
@@ -200,11 +183,9 @@ index 8e03c9ae0bf0..43bef114a238 100644
start_index = wbc->range_cyclic ? mapping->writeback_index : 0;
index = start_index;
-diff --git a/fs/ceph/cache.c b/fs/ceph/cache.c
-index bf56392ecec2..b44021ab6aa9 100644
--- a/fs/ceph/cache.c
+++ b/fs/ceph/cache.c
-@@ -144,7 +144,7 @@ static void ceph_fscache_inode_now_uncached(void* cookie_netfs_data)
+@@ -201,7 +201,7 @@
pgoff_t first;
int loop, nr_pages;
@@ -213,11 +194,9 @@ index bf56392ecec2..b44021ab6aa9 100644
first = 0;
dout("ceph inode 0x%p now uncached", ci);
-diff --git a/fs/cifs/cache.c b/fs/cifs/cache.c
-index 6c665bf4a27c..e3c9a48b5d10 100644
--- a/fs/cifs/cache.c
+++ b/fs/cifs/cache.c
-@@ -299,7 +299,7 @@ static void cifs_fscache_inode_now_uncached(void *cookie_netfs_data)
+@@ -299,7 +299,7 @@
pgoff_t first;
int loop, nr_pages;
@@ -226,11 +205,9 @@ index 6c665bf4a27c..e3c9a48b5d10 100644
first = 0;
cifs_dbg(FYI, "%s: cifs inode 0x%p now uncached\n", __func__, cifsi);
-diff --git a/fs/dax.c b/fs/dax.c
-index b9e50fe0d500..b501e28b2ccc 100644
--- a/fs/dax.c
+++ b/fs/dax.c
-@@ -839,7 +839,7 @@ int dax_writeback_mapping_range(struct address_space *mapping,
+@@ -753,7 +753,7 @@
tag_pages_for_writeback(mapping, start_index, end_index);
@@ -239,11 +216,9 @@ index b9e50fe0d500..b501e28b2ccc 100644
while (!done) {
pvec.nr = find_get_entries_tag(mapping, start_index,
PAGECACHE_TAG_TOWRITE, PAGEVEC_SIZE,
-diff --git a/fs/ext4/file.c b/fs/ext4/file.c
-index 15e29136248b..87e07c6360b2 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
-@@ -499,7 +499,7 @@ static int ext4_find_unwritten_pgoff(struct inode *inode,
+@@ -482,7 +482,7 @@
index = startoff >> PAGE_SHIFT;
end = (endoff - 1) >> PAGE_SHIFT;
@@ -252,11 +227,9 @@ index 15e29136248b..87e07c6360b2 100644
do {
int i, num;
unsigned long nr_pages;
-diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
-index 57f67102bc2e..d67a6d36cfb8 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
-@@ -1669,7 +1669,7 @@ static void mpage_release_unused_pages(struct mpage_da_data *mpd,
+@@ -1669,7 +1669,7 @@
ext4_es_remove_extent(inode, start, last - start + 1);
}
@@ -265,7 +238,7 @@ index 57f67102bc2e..d67a6d36cfb8 100644
while (index <= end) {
nr_pages = pagevec_lookup(&pvec, mapping, index, PAGEVEC_SIZE);
if (nr_pages == 0)
-@@ -2297,7 +2297,7 @@ static int mpage_map_and_submit_buffers(struct mpage_da_data *mpd)
+@@ -2297,7 +2297,7 @@
lblk = start << bpp_bits;
pblock = mpd->map.m_pblk;
@@ -274,7 +247,7 @@ index 57f67102bc2e..d67a6d36cfb8 100644
while (start <= end) {
nr_pages = pagevec_lookup(&pvec, inode->i_mapping, start,
PAGEVEC_SIZE);
-@@ -2573,7 +2573,7 @@ static int mpage_prepare_extent_to_map(struct mpage_da_data *mpd)
+@@ -2573,7 +2573,7 @@
else
tag = PAGECACHE_TAG_DIRTY;
@@ -283,11 +256,9 @@ index 57f67102bc2e..d67a6d36cfb8 100644
mpd->map.m_len = 0;
mpd->next_page = index;
while (index <= end) {
-diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
-index 06f7854d4e52..ee50cbd674e8 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
-@@ -304,7 +304,7 @@ long sync_meta_pages(struct f2fs_sb_info *sbi, enum page_type type,
+@@ -304,7 +304,7 @@
};
struct blk_plug plug;
@@ -296,11 +267,9 @@ index 06f7854d4e52..ee50cbd674e8 100644
blk_start_plug(&plug);
-diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
-index 36fe82012a33..f4a5daef0b55 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
-@@ -1569,7 +1569,7 @@ static int f2fs_write_cache_pages(struct address_space *mapping,
+@@ -1570,7 +1570,7 @@
int range_whole = 0;
int tag;
@@ -309,11 +278,9 @@ index 36fe82012a33..f4a5daef0b55 100644
if (get_dirty_pages(mapping->host) <=
SM_I(F2FS_M_SB(mapping))->min_hot_blocks)
-diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
-index 666edc49e852..ad179f2ed2a9 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
-@@ -293,7 +293,7 @@ static pgoff_t __get_first_dirty_index(struct address_space *mapping,
+@@ -293,7 +293,7 @@
return 0;
/* find first dirty page index */
@@ -322,11 +289,9 @@ index 666edc49e852..ad179f2ed2a9 100644
nr_pages = pagevec_lookup_tag(&pvec, mapping, &pgofs,
PAGECACHE_TAG_DIRTY, 1);
pgofs = nr_pages ? pvec.pages[0]->index : ULONG_MAX;
-diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
-index 4547c5c5cd98..007f0132e844 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
-@@ -1263,7 +1263,7 @@ static struct page *last_fsync_dnode(struct f2fs_sb_info *sbi, nid_t ino)
+@@ -1263,7 +1263,7 @@
struct pagevec pvec;
struct page *last_page = NULL;
@@ -335,7 +300,7 @@ index 4547c5c5cd98..007f0132e844 100644
index = 0;
end = ULONG_MAX;
-@@ -1417,7 +1417,7 @@ int fsync_node_pages(struct f2fs_sb_info *sbi, struct inode *inode,
+@@ -1417,7 +1417,7 @@
return PTR_ERR_OR_ZERO(last_page);
}
retry:
@@ -344,7 +309,7 @@ index 4547c5c5cd98..007f0132e844 100644
index = 0;
end = ULONG_MAX;
-@@ -1531,7 +1531,7 @@ int sync_node_pages(struct f2fs_sb_info *sbi, struct writeback_control *wbc)
+@@ -1531,7 +1531,7 @@
int nwritten = 0;
int ret = 0;
@@ -353,7 +318,7 @@ index 4547c5c5cd98..007f0132e844 100644
next_step:
index = 0;
-@@ -1635,7 +1635,7 @@ int wait_on_node_pages_writeback(struct f2fs_sb_info *sbi, nid_t ino)
+@@ -1635,7 +1635,7 @@
struct pagevec pvec;
int ret2, ret = 0;
@@ -362,11 +327,9 @@ index 4547c5c5cd98..007f0132e844 100644
while (index <= end) {
int i, nr_pages;
-diff --git a/fs/fscache/page.c b/fs/fscache/page.c
-index c8c4f79c7ce1..2dba99f77395 100644
--- a/fs/fscache/page.c
+++ b/fs/fscache/page.c
-@@ -1175,7 +1175,7 @@ void __fscache_uncache_all_inode_pages(struct fscache_cookie *cookie,
+@@ -1175,7 +1175,7 @@
return;
}
@@ -375,11 +338,9 @@ index c8c4f79c7ce1..2dba99f77395 100644
next = 0;
do {
if (!pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE))
-diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c
-index ed7a2e252ad8..85fb0ea94c3a 100644
--- a/fs/gfs2/aops.c
+++ b/fs/gfs2/aops.c
-@@ -375,7 +375,7 @@ static int gfs2_write_cache_jdata(struct address_space *mapping,
+@@ -375,7 +375,7 @@
int range_whole = 0;
int tag;
@@ -388,11 +349,9 @@ index ed7a2e252ad8..85fb0ea94c3a 100644
if (wbc->range_cyclic) {
writeback_index = mapping->writeback_index; /* prev offset */
index = writeback_index;
-diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
-index d44f5456eb9b..e5d05ccba8b0 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
-@@ -408,7 +408,7 @@ static void remove_inode_hugepages(struct inode *inode, loff_t lstart,
+@@ -408,7 +408,7 @@
memset(&pseudo_vma, 0, sizeof(struct vm_area_struct));
pseudo_vma.vm_flags = (VM_HUGETLB | VM_MAYSHARE | VM_SHARED);
@@ -401,11 +360,9 @@ index d44f5456eb9b..e5d05ccba8b0 100644
next = start;
while (next < end) {
/*
-diff --git a/fs/nfs/fscache-index.c b/fs/nfs/fscache-index.c
-index 777b055063f6..3953961e87d8 100644
--- a/fs/nfs/fscache-index.c
+++ b/fs/nfs/fscache-index.c
-@@ -265,7 +265,7 @@ static void nfs_fscache_inode_now_uncached(void *cookie_netfs_data)
+@@ -265,7 +265,7 @@
pgoff_t first;
int loop, nr_pages;
@@ -414,11 +371,9 @@ index 777b055063f6..3953961e87d8 100644
first = 0;
dprintk("NFS: nfs_inode_now_uncached: nfs_inode 0x%p\n", nfsi);
-diff --git a/fs/nilfs2/btree.c b/fs/nilfs2/btree.c
-index 06ffa135dfa6..5e90c5bd91d9 100644
--- a/fs/nilfs2/btree.c
+++ b/fs/nilfs2/btree.c
-@@ -2156,7 +2156,7 @@ static void nilfs_btree_lookup_dirty_buffers(struct nilfs_bmap *btree,
+@@ -2156,7 +2156,7 @@
level++)
INIT_LIST_HEAD(&lists[level]);
@@ -427,11 +382,9 @@ index 06ffa135dfa6..5e90c5bd91d9 100644
while (pagevec_lookup_tag(&pvec, btcache, &index, PAGECACHE_TAG_DIRTY,
PAGEVEC_SIZE)) {
-diff --git a/fs/nilfs2/page.c b/fs/nilfs2/page.c
-index f11a3ad2df0c..694fd039a1ce 100644
--- a/fs/nilfs2/page.c
+++ b/fs/nilfs2/page.c
-@@ -255,7 +255,7 @@ int nilfs_copy_dirty_pages(struct address_space *dmap,
+@@ -255,7 +255,7 @@
pgoff_t index = 0;
int err = 0;
@@ -440,7 +393,7 @@ index f11a3ad2df0c..694fd039a1ce 100644
repeat:
if (!pagevec_lookup_tag(&pvec, smap, &index, PAGECACHE_TAG_DIRTY,
PAGEVEC_SIZE))
-@@ -310,7 +310,7 @@ void nilfs_copy_back_pages(struct address_space *dmap,
+@@ -310,7 +310,7 @@
pgoff_t index = 0;
int err;
@@ -449,7 +402,7 @@ index f11a3ad2df0c..694fd039a1ce 100644
repeat:
n = pagevec_lookup(&pvec, smap, index, PAGEVEC_SIZE);
if (!n)
-@@ -375,7 +375,7 @@ void nilfs_clear_dirty_pages(struct address_space *mapping, bool silent)
+@@ -375,7 +375,7 @@
unsigned int i;
pgoff_t index = 0;
@@ -458,7 +411,7 @@ index f11a3ad2df0c..694fd039a1ce 100644
while (pagevec_lookup_tag(&pvec, mapping, &index, PAGECACHE_TAG_DIRTY,
PAGEVEC_SIZE)) {
-@@ -520,7 +520,7 @@ unsigned long nilfs_find_uncommitted_extent(struct inode *inode,
+@@ -520,7 +520,7 @@
index = start_blk >> (PAGE_SHIFT - inode->i_blkbits);
nblocks_in_page = 1U << (PAGE_SHIFT - inode->i_blkbits);
@@ -467,11 +420,9 @@ index f11a3ad2df0c..694fd039a1ce 100644
repeat:
pvec.nr = find_get_pages_contig(inode->i_mapping, index, PAGEVEC_SIZE,
-diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c
-index 70ded52dc1dd..0d56c4ea7216 100644
--- a/fs/nilfs2/segment.c
+++ b/fs/nilfs2/segment.c
-@@ -708,7 +708,7 @@ static size_t nilfs_lookup_dirty_data_buffers(struct inode *inode,
+@@ -708,7 +708,7 @@
index = start >> PAGE_SHIFT;
last = end >> PAGE_SHIFT;
}
@@ -480,7 +431,7 @@ index 70ded52dc1dd..0d56c4ea7216 100644
repeat:
if (unlikely(index > last) ||
!pagevec_lookup_tag(&pvec, mapping, &index, PAGECACHE_TAG_DIRTY,
-@@ -757,7 +757,7 @@ static void nilfs_lookup_dirty_node_buffers(struct inode *inode,
+@@ -757,7 +757,7 @@
unsigned int i;
pgoff_t index = 0;
@@ -489,24 +440,9 @@ index 70ded52dc1dd..0d56c4ea7216 100644
while (pagevec_lookup_tag(&pvec, mapping, &index, PAGECACHE_TAG_DIRTY,
PAGEVEC_SIZE)) {
-diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
-index 17f27a2fb5e2..c89d86a9fa1e 100644
---- a/fs/xfs/xfs_file.c
-+++ b/fs/xfs/xfs_file.c
-@@ -1059,7 +1059,7 @@ xfs_find_get_desired_pgoff(
- loff_t lastoff = startoff;
- bool found = false;
-
-- pagevec_init(&pvec, 0);
-+ pagevec_init(&pvec);
-
- index = startoff >> PAGE_SHIFT;
- endoff = XFS_FSB_TO_B(mp, map->br_startoff + map->br_blockcount);
-diff --git a/include/linux/pagevec.h b/include/linux/pagevec.h
-index 0ed6c6f31f0b..640b7cd07802 100644
--- a/include/linux/pagevec.h
+++ b/include/linux/pagevec.h
-@@ -16,7 +16,6 @@ struct address_space;
+@@ -16,7 +16,6 @@
struct pagevec {
unsigned long nr;
@@ -514,7 +450,7 @@ index 0ed6c6f31f0b..640b7cd07802 100644
bool drained;
struct page *pages[PAGEVEC_SIZE];
};
-@@ -34,10 +33,9 @@ unsigned pagevec_lookup_tag(struct pagevec *pvec,
+@@ -34,10 +33,9 @@
struct address_space *mapping, pgoff_t *index, int tag,
unsigned nr_pages);
@@ -526,11 +462,9 @@ index 0ed6c6f31f0b..640b7cd07802 100644
pvec->drained = false;
}
-diff --git a/mm/filemap.c b/mm/filemap.c
-index 4d1498b49c0d..f7b3f22535fa 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
-@@ -501,7 +501,7 @@ bool filemap_range_has_page(struct address_space *mapping,
+@@ -502,7 +502,7 @@
if (mapping->nrpages == 0)
return false;
@@ -539,7 +473,7 @@ index 4d1498b49c0d..f7b3f22535fa 100644
if (!pagevec_lookup(&pvec, mapping, index, 1))
return false;
ret = (pvec.pages[0]->index <= end);
-@@ -522,7 +522,7 @@ static int __filemap_fdatawait_range(struct address_space *mapping,
+@@ -522,7 +522,7 @@
if (end_byte < start_byte)
return;
@@ -548,11 +482,9 @@ index 4d1498b49c0d..f7b3f22535fa 100644
while ((index <= end) &&
(nr_pages = pagevec_lookup_tag(&pvec, mapping, &index,
PAGECACHE_TAG_WRITEBACK,
-diff --git a/mm/mlock.c b/mm/mlock.c
-index b562b5523a65..6b28e70edeab 100644
--- a/mm/mlock.c
+++ b/mm/mlock.c
-@@ -288,7 +288,7 @@ static void __munlock_pagevec(struct pagevec *pvec, struct zone *zone)
+@@ -288,7 +288,7 @@
struct pagevec pvec_putback;
int pgrescued = 0;
@@ -561,7 +493,7 @@ index b562b5523a65..6b28e70edeab 100644
/* Phase 1: page isolation */
spin_lock_irq(zone_lru_lock(zone));
-@@ -448,7 +448,7 @@ void munlock_vma_pages_range(struct vm_area_struct *vma,
+@@ -448,7 +448,7 @@
struct zone *zone;
int zoneid;
@@ -570,11 +502,9 @@ index b562b5523a65..6b28e70edeab 100644
/*
* Although FOLL_DUMP is intended for get_dump_page(),
* it just so happens that its special treatment of the
-diff --git a/mm/page-writeback.c b/mm/page-writeback.c
-index 30a8686045cd..cd3b1753602c 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
-@@ -2167,7 +2167,7 @@ int write_cache_pages(struct address_space *mapping,
+@@ -2151,7 +2151,7 @@
int range_whole = 0;
int tag;
@@ -583,11 +513,9 @@ index 30a8686045cd..cd3b1753602c 100644
if (wbc->range_cyclic) {
writeback_index = mapping->writeback_index; /* prev offset */
index = writeback_index;
-diff --git a/mm/shmem.c b/mm/shmem.c
-index 04cfc7bce13f..aab306f3f4b4 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
-@@ -732,7 +732,7 @@ void shmem_unlock_mapping(struct address_space *mapping)
+@@ -745,7 +745,7 @@
pgoff_t indices[PAGEVEC_SIZE];
pgoff_t index = 0;
@@ -596,7 +524,7 @@ index 04cfc7bce13f..aab306f3f4b4 100644
/*
* Minor point, but we might as well stop if someone else SHM_LOCKs it.
*/
-@@ -775,7 +775,7 @@ static void shmem_undo_range(struct inode *inode, loff_t lstart, loff_t lend,
+@@ -788,7 +788,7 @@
if (lend == -1)
end = -1; /* unsigned, so actually very big */
@@ -605,7 +533,7 @@ index 04cfc7bce13f..aab306f3f4b4 100644
index = start;
while (index < end) {
pvec.nr = find_get_entries(mapping, index,
-@@ -2510,7 +2510,7 @@ static pgoff_t shmem_seek_hole_data(struct address_space *mapping,
+@@ -2499,7 +2499,7 @@
bool done = false;
int i;
@@ -614,11 +542,9 @@ index 04cfc7bce13f..aab306f3f4b4 100644
pvec.nr = 1; /* start small: we may be there already */
while (!done) {
pvec.nr = find_get_entries(mapping, index,
-diff --git a/mm/swap.c b/mm/swap.c
-index 0676d6a55f65..a2bdb05061c5 100644
--- a/mm/swap.c
+++ b/mm/swap.c
-@@ -210,7 +210,7 @@ static void pagevec_lru_move_fn(struct pagevec *pvec,
+@@ -210,7 +210,7 @@
}
if (pgdat)
spin_unlock_irqrestore(&pgdat->lru_lock, flags);
@@ -627,7 +553,7 @@ index 0676d6a55f65..a2bdb05061c5 100644
pagevec_reinit(pvec);
}
-@@ -820,7 +820,7 @@ void __pagevec_release(struct pagevec *pvec)
+@@ -831,7 +831,7 @@
lru_add_drain();
pvec->drained = true;
}
@@ -636,11 +562,9 @@ index 0676d6a55f65..a2bdb05061c5 100644
pagevec_reinit(pvec);
}
EXPORT_SYMBOL(__pagevec_release);
-diff --git a/mm/truncate.c b/mm/truncate.c
-index ba6ca3291685..7197a5bb290a 100644
--- a/mm/truncate.c
+++ b/mm/truncate.c
-@@ -322,7 +322,7 @@ void truncate_inode_pages_range(struct address_space *mapping,
+@@ -330,7 +330,7 @@
else
end = (lend + 1) >> PAGE_SHIFT;
@@ -649,7 +573,7 @@ index ba6ca3291685..7197a5bb290a 100644
index = start;
while (index < end && pagevec_lookup_entries(&pvec, mapping, index,
min(end - index, (pgoff_t)PAGEVEC_SIZE),
-@@ -335,7 +335,7 @@ void truncate_inode_pages_range(struct address_space *mapping,
+@@ -342,7 +342,7 @@
*/
struct pagevec locked_pvec;
@@ -658,7 +582,7 @@ index ba6ca3291685..7197a5bb290a 100644
for (i = 0; i < pagevec_count(&pvec); i++) {
struct page *page = pvec.pages[i];
-@@ -554,7 +554,7 @@ unsigned long invalidate_mapping_pages(struct address_space *mapping,
+@@ -553,7 +553,7 @@
unsigned long count = 0;
int i;
@@ -667,7 +591,7 @@ index ba6ca3291685..7197a5bb290a 100644
while (index <= end && pagevec_lookup_entries(&pvec, mapping, index,
min(end - index, (pgoff_t)PAGEVEC_SIZE - 1) + 1,
indices)) {
-@@ -678,7 +678,7 @@ int invalidate_inode_pages2_range(struct address_space *mapping,
+@@ -677,7 +677,7 @@
if (mapping->nrpages == 0 && mapping->nrexceptional == 0)
goto out;
diff --git a/series.conf b/series.conf
index f2e0213e3d..5da70910b1 100644
--- a/series.conf
+++ b/series.conf
@@ -3561,6 +3561,7 @@
patches.fixes/xfs-check-if-an-inode-is-cached-and-allocated.patch
patches.fixes/vfs-Add-page_cache_seek_hole_data-helper.patch
patches.fixes/vfs-Add-iomap_seek_hole-and-iomap_seek_data-helpers.patch
+ patches.fixes/xfs-Switch-to-iomap-for-SEEK_HOLE-SEEK_DATA.patch
patches.drivers/ipmi_ssif-unlock-on-allocation-failure
patches.drivers/0007-ipmi_ssif-remove-redundant-null-check-on-array-clien.patch
patches.drivers/0008-ipmi-Use-the-proper-default-value-for-register-size-.patch