Patch "xfs: Fix missed holes in SEEK_HOLE implementation" has been added to the 4.11-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
xfs: Fix missed holes in SEEK_HOLE implementation
to the 4.11-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
xfs-fix-missed-holes-in-seek_hole-implementation.patch
and it can be found in the queue-4.11 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
5375023ae1266553a7baa0845e82917d8803f48cMon Sep 17 00:00:00 2001
From: Jan Kara <[email protected]>
Date: Thu, 18 May 2017 16:36:22 -0700
Subject: xfs: Fix missed holes in SEEK_HOLE implementation
From: Jan Kara <[email protected]>
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.
--- fs/xfs/xfs_file.c | 29 +++++++++-------------------- 1 file changed, 9 insertions(+), 20 deletions(-)
fs/xfs/xfs_file.c +9 -20
@@ -1076,17 +1076,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;
@@ -1098,18 +1087,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);/*
Patches currently in stable-queue which might be from [email protected] are
queue-4.11/xfs-fix-missed-holes-in-seek_hole-implementation.patch queue-4.11/mm-avoid-spurious-bad-pmd-warning-messages.patch queue-4.11/xfs-fix-off-by-one-on-max-nr_pages-in-xfs_find_get_desired_pgoff.patch queue-4.11/dax-fix-race-between-colliding-pmd-pte-entries.patch