aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/file.c
diff options
context:
space:
mode:
authorMiao Xie <miaox@cn.fujitsu.com>2012-12-05 05:54:52 -0500
committerChris Mason <chris.mason@fusionio.com>2012-12-16 20:46:20 -0500
commit7426cc04d407621773af3a0403e57642e40c36bf (patch)
treec4ee079d8f66cd23ac58f770f618a02f419dd01e /fs/btrfs/file.c
parent0061280d2c7240805cfd7b1f493da967c97c2f34 (diff)
Btrfs: punch hole past the end of the file
Since we can pre-allocate the space past EOF, we should be able to reclaim that space if we need. This patch implements it by removing the EOF check. Though the manual of fallocate command says we can use truncate command to reclaim the pre-allocated space which past EOF, but because truncate command changes the file size, we must run several commands to reclaim the space if we don't want to change the file size, so it is not a good choice. Signed-off-by: Miao Xie <miaox@cn.fujitsu.com> Signed-off-by: Chris Mason <chris.mason@fusionio.com>
Diffstat (limited to 'fs/btrfs/file.c')
-rw-r--r--fs/btrfs/file.c22
1 files changed, 12 insertions, 10 deletions
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index 700ffd266da3..71c2dc1ea15a 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -1873,26 +1873,28 @@ static int btrfs_punch_hole(struct inode *inode, loff_t offset, loff_t len)
1873 btrfs_wait_ordered_range(inode, offset, len); 1873 btrfs_wait_ordered_range(inode, offset, len);
1874 1874
1875 mutex_lock(&inode->i_mutex); 1875 mutex_lock(&inode->i_mutex);
1876 if (offset >= inode->i_size) { 1876 /*
1877 mutex_unlock(&inode->i_mutex); 1877 * We needn't truncate any page which is beyond the end of the file
1878 return 0; 1878 * because we are sure there is no data there.
1879 } 1879 */
1880
1881 /* 1880 /*
1882 * Only do this if we are in the same page and we aren't doing the 1881 * Only do this if we are in the same page and we aren't doing the
1883 * entire page. 1882 * entire page.
1884 */ 1883 */
1885 if (same_page && len < PAGE_CACHE_SIZE) { 1884 if (same_page && len < PAGE_CACHE_SIZE) {
1886 ret = btrfs_truncate_page(inode, offset, len, 0); 1885 if (offset < round_up(inode->i_size, PAGE_CACHE_SIZE))
1886 ret = btrfs_truncate_page(inode, offset, len, 0);
1887 mutex_unlock(&inode->i_mutex); 1887 mutex_unlock(&inode->i_mutex);
1888 return ret; 1888 return ret;
1889 } 1889 }
1890 1890
1891 /* zero back part of the first page */ 1891 /* zero back part of the first page */
1892 ret = btrfs_truncate_page(inode, offset, 0, 0); 1892 if (offset < round_up(inode->i_size, PAGE_CACHE_SIZE)) {
1893 if (ret) { 1893 ret = btrfs_truncate_page(inode, offset, 0, 0);
1894 mutex_unlock(&inode->i_mutex); 1894 if (ret) {
1895 return ret; 1895 mutex_unlock(&inode->i_mutex);
1896 return ret;
1897 }
1896 } 1898 }
1897 1899
1898 /* zero the front end of the last page */ 1900 /* zero the front end of the last page */