1 ext4: fix off-by-one on max nr_pages in ext4_find_unwritten_pgoff()
3 From: Eryu Guan <eguan@redhat.com>
5 ext4_find_unwritten_pgoff() is used to search for offset of hole or
6 data in page range [index, end] (both inclusive), and the max number
7 of pages to search should be at least one, if end == index.
8 Otherwise the only page is missed and no hole or data is found,
11 When block size is smaller than page size, this can be demonstrated
12 by preallocating a file with size smaller than page size and writing
13 data to the last block. E.g. run this xfs_io command on a 1k block
14 size ext4 on x86_64 host.
16 # xfs_io -fc "falloc 0 3k" -c "pwrite 2k 1k" \
17 -c "seek -d 0" /mnt/ext4/testfile
18 wrote 1024/1024 bytes at offset 2048
19 1 KiB, 1 ops; 0.0000 sec (42.459 MiB/sec and 43478.2609 ops/sec)
23 Data at offset 2k was missed, and lseek(2) returned ENXIO.
25 This is unconvered by generic/285 subtest 07 and 08 on ppc64 host,
26 where pagesize is 64k. Because a recent change to generic/285
27 reduced the preallocated file size to smaller than 64k.
29 Signed-off-by: Eryu Guan <eguan@redhat.com>
30 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
31 Reviewed-by: Jan Kara <jack@suse.cz>
34 1 file changed, 1 insertion(+), 1 deletion(-)
36 diff --git a/fs/ext4/file.c b/fs/ext4/file.c
37 index 831fd6b..7b206e5 100644
40 @@ -481,7 +481,7 @@ static int ext4_find_unwritten_pgoff(struct inode *inode,
42 unsigned long nr_pages;
44 - num = min_t(pgoff_t, end - index, PAGEVEC_SIZE);
45 + num = min_t(pgoff_t, end - index, PAGEVEC_SIZE - 1) + 1;
46 nr_pages = pagevec_lookup(&pvec, inode->i_mapping, index,