aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosef Bacik <josef@redhat.com>2009-10-01 17:10:23 -0400
committerChris Mason <chris.mason@oracle.com>2009-10-01 17:10:23 -0400
commitfbf190874407f23d2891b53ffdf7d3c6be8d47ff (patch)
treec60ab388e2b19b02fd3bbcef76498a3520f9dcbd
parentab93dbecfba72bbc04b7036343d180aaff1b61a3 (diff)
Btrfs: fix data space leak fix
There is a problem where page_mkwrite can be called on a dirtied page that already has a delalloc range associated with it. The fix is to clear any delalloc bits for the range we are dirtying so the space accounting gets handled properly. This is the same thing we do in the normal write case, so we are consistent across the board. With this patch we no longer leak reserved space. Signed-off-by: Josef Bacik <jbacik@redhat.com> Signed-off-by: Chris Mason <chris.mason@oracle.com>
-rw-r--r--fs/btrfs/inode.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 3cc5677f5440..3a6f953337b5 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -4909,10 +4909,21 @@ again:
4909 goto again; 4909 goto again;
4910 } 4910 }
4911 4911
4912 /*
4913 * XXX - page_mkwrite gets called every time the page is dirtied, even
4914 * if it was already dirty, so for space accounting reasons we need to
4915 * clear any delalloc bits for the range we are fixing to save. There
4916 * is probably a better way to do this, but for now keep consistent with
4917 * prepare_pages in the normal write path.
4918 */
4919 clear_extent_bits(&BTRFS_I(inode)->io_tree, page_start, page_end,
4920 EXTENT_DIRTY | EXTENT_DELALLOC, GFP_NOFS);
4921
4912 ret = btrfs_set_extent_delalloc(inode, page_start, page_end); 4922 ret = btrfs_set_extent_delalloc(inode, page_start, page_end);
4913 if (ret) { 4923 if (ret) {
4914 unlock_extent(io_tree, page_start, page_end, GFP_NOFS); 4924 unlock_extent(io_tree, page_start, page_end, GFP_NOFS);
4915 ret = VM_FAULT_SIGBUS; 4925 ret = VM_FAULT_SIGBUS;
4926 btrfs_free_reserved_data_space(root, inode, PAGE_CACHE_SIZE);
4916 goto out_unlock; 4927 goto out_unlock;
4917 } 4928 }
4918 ret = 0; 4929 ret = 0;