aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorQu Wenruo <quwenruo@cn.fujitsu.com>2015-10-14 03:26:13 -0400
committerChris Mason <clm@fb.com>2015-10-20 22:07:29 -0400
commit0f6925fa2907df58496cabc33fa4677c635e2223 (patch)
tree85b4f57ea06fb3f0b0cbb50412742d64719defbb /fs
parentdc6c5fb3b514221f2e9d21ee626a9d95d3418dff (diff)
btrfs: Avoid truncate tailing page if fallocate range doesn't exceed inode size
Current code will always truncate tailing page if its alloc_start is smaller than inode size. For example, the file extent layout is like: 0 4K 8K 16K 32K |<-----Extent A---------------->| |<--Inode size: 18K---------->| But if calling fallocate even for range [0,4K), it will cause btrfs to re-truncate the range [16,32K), causing COW and a new extent. 0 4K 8K 16K 32K |///////| <- Fallocate call range |<-----Extent A-------->|<--B-->| The cause is quite easy, just a careless btrfs_truncate_inode() in a else branch without extra judgment. Fix it by add judgment on whether the fallocate range is beyond isize. Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com> Signed-off-by: Chris Mason <clm@fb.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/file.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index b823fac91c92..8c6f247ba81d 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -2584,7 +2584,7 @@ static long btrfs_fallocate(struct file *file, int mode,
2584 alloc_start); 2584 alloc_start);
2585 if (ret) 2585 if (ret)
2586 goto out; 2586 goto out;
2587 } else { 2587 } else if (offset + len > inode->i_size) {
2588 /* 2588 /*
2589 * If we are fallocating from the end of the file onward we 2589 * If we are fallocating from the end of the file onward we
2590 * need to zero out the end of the page if i_size lands in the 2590 * need to zero out the end of the page if i_size lands in the