1 ext4: fix SEEK_HOLE/SEEK_DATA for blocksize < pagesize
3 From: Jan Kara <jack@suse.cz>
5 ext4_find_unwritten_pgoff() does not properly handle a situation when
6 starting index is in the middle of a page and blocksize < pagesize. The
7 following command shows the bug on filesystem with 1k blocksize:
9 xfs_io -f -c "falloc 0 4k" \
14 In this example, neither lseek(fd, 1024, SEEK_HOLE) nor lseek(fd, 2048,
15 SEEK_DATA) will return the correct result.
17 Fix the problem by neglecting buffers in a page before starting offset.
19 Reported-by: Andreas Gruenbacher <agruenba@redhat.com>
20 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
21 Signed-off-by: Jan Kara <jack@suse.cz>
22 CC: stable@vger.kernel.org # 3.8+
24 fs/ext4/file.c | 3 +++
25 1 file changed, 3 insertions(+)
27 This is an easy fix for the SEEK_HOLE/SEEK_DATA bug Andreas found. Longer
28 term we want to move ext4 to use page_cache_seek_hole_data() however for
29 stable backporting this is more suitable.
31 diff --git a/fs/ext4/file.c b/fs/ext4/file.c
32 index b221d0b546b0..8ba34cbe8fe7 100644
35 @@ -530,6 +530,8 @@ static int ext4_find_unwritten_pgoff(struct inode *inode,
36 lastoff = page_offset(page);
37 bh = head = page_buffers(page);
39 + if (lastoff + bh->b_size <= startoff)
41 if (buffer_uptodate(bh) ||
42 buffer_unwritten(bh)) {
43 if (whence == SEEK_DATA)
44 @@ -544,6 +546,7 @@ static int ext4_find_unwritten_pgoff(struct inode *inode,
49 lastoff += bh->b_size;