Btrfs: fix the page that is beyond EOF
authorMiao Xie <miaox@cn.fujitsu.com>
Wed, 5 Dec 2012 10:54:12 +0000 (10:54 +0000)
committerChris Mason <chris.mason@fusionio.com>
Mon, 17 Dec 2012 01:46:19 +0000 (20:46 -0500)
commit0061280d2c7240805cfd7b1f493da967c97c2f34
tree3808aee5875cd38651a580fe825925de414f345c
parent6347b3c433a4cff00eb2299c7f2c7d1d8b24c1fc
Btrfs: fix the page that is beyond EOF

Steps to reproduce:
 # mkfs.btrfs <disk>
 # mount <disk> <mnt>
 # dd if=/dev/zero of=<mnt>/<file> bs=512 seek=5 count=8
 # fallocate -p -o 2048 -l 16384 <mnt>/<file>
 # dd if=/dev/zero of=<mnt>/<file> bs=4096 seek=3 count=8 conv=notrunc,nocreat
 # umount <mnt>
 # dmesg
 WARNING: at fs/btrfs/inode.c:7140 btrfs_destroy_inode+0x2eb/0x330

The reason is that we inputed a range which is beyond the end of the file. And
because the end of this range was not page-aligned, we had to truncate the last
page in this range, this operation is similar to a buffered file write. In other
words, we reserved enough space and clear the data which was in the hole range
on that page. But when we expanded that test file, write the data into the same
page, we forgot that we have reserved enough space for the buffered write of
that page because in most cases there is no page that is beyond the end of
the file. As a result, we reserved the space twice.

In fact, we needn't truncate the page if it is beyond the end of the file, just
release the allocated space in that range. Fix the above problem by this way.

Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
Signed-off-by: Chris Mason <chris.mason@fusionio.com>
fs/btrfs/file.c