--- /dev/null
+From 5375023ae1266553a7baa0845e82917d8803f48c Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Thu, 18 May 2017 16:36:22 -0700
+Subject: xfs: Fix missed holes in SEEK_HOLE implementation
+
+From: Jan Kara <jack@suse.cz>
+
+commit 5375023ae1266553a7baa0845e82917d8803f48c upstream.
+
+XFS SEEK_HOLE implementation could miss a hole in an unwritten extent as
+can be seen by the following command:
+
+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 (49.312 MiB/sec and 12623.9856 ops/sec)
+wrote 8192/8192 bytes at offset 131072
+8 KiB, 2 ops; 0.0000 sec (70.383 MiB/sec and 18018.0180 ops/sec)
+Whence Result
+HOLE 139264
+
+Where we can see that hole at offset 56k was just ignored by SEEK_HOLE
+implementation. The bug is in xfs_find_get_desired_pgoff() which does
+not properly detect the case when pages are not contiguous.
+
+Fix the problem by properly detecting when found page has larger offset
+than expected.
+
+Fixes: d126d43f631f996daeee5006714fed914be32368
+Signed-off-by: Jan Kara <jack@suse.cz>
+Reviewed-by: Brian Foster <bfoster@redhat.com>
+Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
+Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/xfs/xfs_file.c | 29 +++++++++--------------------
+ 1 file changed, 9 insertions(+), 20 deletions(-)
+
+--- a/fs/xfs/xfs_file.c
++++ b/fs/xfs/xfs_file.c
+@@ -1235,17 +1235,6 @@ xfs_find_get_desired_pgoff(
+ break;
+ }
+
+- /*
+- * At lease we found one page. If this is the first time we
+- * step into the loop, and if the first page index offset is
+- * greater than the given search offset, a hole was found.
+- */
+- if (type == HOLE_OFF && lastoff == startoff &&
+- lastoff < page_offset(pvec.pages[0])) {
+- found = true;
+- break;
+- }
+-
+ for (i = 0; i < nr_pages; i++) {
+ struct page *page = pvec.pages[i];
+ loff_t b_offset;
+@@ -1257,18 +1246,18 @@ xfs_find_get_desired_pgoff(
+ * file mapping. However, page->index will not change
+ * because we have a reference on the page.
+ *
+- * Searching done if the page index is out of range.
+- * If the current offset is not reaches the end of
+- * the specified search range, there should be a hole
+- * between them.
++ * If current page offset is beyond where we've ended,
++ * we've found a hole.
+ */
+- if (page->index > end) {
+- if (type == HOLE_OFF && lastoff < endoff) {
+- *offset = lastoff;
+- found = true;
+- }
++ 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);
+ /*
--- /dev/null
+From 8affebe16d79ebefb1d9d6d56a46dc89716f9453 Mon Sep 17 00:00:00 2001
+From: Eryu Guan <eguan@redhat.com>
+Date: Tue, 23 May 2017 08:30:46 -0700
+Subject: xfs: fix off-by-one on max nr_pages in xfs_find_get_desired_pgoff()
+
+From: Eryu Guan <eguan@redhat.com>
+
+commit 8affebe16d79ebefb1d9d6d56a46dc89716f9453 upstream.
+
+xfs_find_get_desired_pgoff() is used to search for offset of hole or
+data in page range [index, end] (both inclusive), and the max number
+of pages to search should be at least one, if end == index.
+Otherwise the only page is missed and no hole or data is found,
+which is not correct.
+
+When block size is smaller than page size, this can be demonstrated
+by preallocating a file with size smaller than page size and writing
+data to the last block. E.g. run this xfs_io command on a 1k block
+size XFS on x86_64 host.
+
+ # xfs_io -fc "falloc 0 3k" -c "pwrite 2k 1k" \
+ -c "seek -d 0" /mnt/xfs/testfile
+ wrote 1024/1024 bytes at offset 2048
+ 1 KiB, 1 ops; 0.0000 sec (33.675 MiB/sec and 34482.7586 ops/sec)
+ Whence Result
+ DATA EOF
+
+Data at offset 2k was missed, and lseek(2) returned ENXIO.
+
+This is uncovered by generic/285 subtest 07 and 08 on ppc64 host,
+where pagesize is 64k. Because a recent change to generic/285
+reduced the preallocated file size to smaller than 64k.
+
+Signed-off-by: Eryu Guan <eguan@redhat.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
+Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/xfs/xfs_file.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/xfs/xfs_file.c
++++ b/fs/xfs/xfs_file.c
+@@ -1208,7 +1208,7 @@ xfs_find_get_desired_pgoff(
+ unsigned nr_pages;
+ unsigned int i;
+
+- want = min_t(pgoff_t, end - index, PAGEVEC_SIZE);
++ want = min_t(pgoff_t, end - index, PAGEVEC_SIZE - 1) + 1;
+ nr_pages = pagevec_lookup(&pvec, inode->i_mapping, index,
+ want);
+ /*