summaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
authorYan Zheng <zheng.yan@oracle.com>2008-12-19 10:58:46 -0500
committerChris Mason <chris.mason@oracle.com>2008-12-19 10:58:46 -0500
commit34bf63c4ddddd92bfba3387d134c37bf4426b2ce (patch)
treea7a2f1fc2d88cb5a5b0a1ca54aa9647ec6e51fa4 /fs
parentab67b7c1f780a8a321fe7ee49117775009350fb3 (diff)
downloadlinux-3.10-34bf63c4ddddd92bfba3387d134c37bf4426b2ce.tar.gz
linux-3.10-34bf63c4ddddd92bfba3387d134c37bf4426b2ce.tar.bz2
linux-3.10-34bf63c4ddddd92bfba3387d134c37bf4426b2ce.zip
Btrfs: properly update block accounting for metadata
This adds the missing block accounting code to finish_current_insert and makes block accounting for root item properly protected by the delalloc spin lock. Signed-off-by: Yan Zheng <zheng.yan@oracle.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/extent-tree.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 9ef2a2be268..274bb91efa2 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -1051,11 +1051,11 @@ search:
super_used = btrfs_super_bytes_used(&info->super_copy);
btrfs_set_super_bytes_used(&info->super_copy,
super_used - bytes_freed);
- spin_unlock(&info->delalloc_lock);
root_used = btrfs_root_used(&extent_root->root_item);
btrfs_set_root_used(&extent_root->root_item,
root_used - bytes_freed);
+ spin_unlock(&info->delalloc_lock);
/* delete the items */
ret = btrfs_del_items(trans, extent_root, path,
@@ -2242,6 +2242,7 @@ again:
extent_op->bytenr + extent_op->num_bytes - 1,
EXTENT_WRITEBACK, GFP_NOFS);
if (extent_op->del) {
+ u64 used;
list_del_init(&extent_op->list);
unlock_extent(&info->extent_ins, extent_op->bytenr,
extent_op->bytenr + extent_op->num_bytes
@@ -2253,6 +2254,15 @@ again:
extent_op->num_bytes, 0);
mutex_unlock(&extent_root->fs_info->pinned_mutex);
+ spin_lock(&info->delalloc_lock);
+ used = btrfs_super_bytes_used(&info->super_copy);
+ btrfs_set_super_bytes_used(&info->super_copy,
+ used - extent_op->num_bytes);
+ used = btrfs_root_used(&extent_root->root_item);
+ btrfs_set_root_used(&extent_root->root_item,
+ used - extent_op->num_bytes);
+ spin_unlock(&info->delalloc_lock);
+
ret = update_block_group(trans, extent_root,
extent_op->bytenr,
extent_op->num_bytes,
@@ -2467,12 +2477,12 @@ static int __free_extent(struct btrfs_trans_handle *trans,
super_used = btrfs_super_bytes_used(&info->super_copy);
btrfs_set_super_bytes_used(&info->super_copy,
super_used - num_bytes);
- spin_unlock(&info->delalloc_lock);
/* block accounting for root item */
root_used = btrfs_root_used(&root->root_item);
btrfs_set_root_used(&root->root_item,
root_used - num_bytes);
+ spin_unlock(&info->delalloc_lock);
ret = btrfs_del_items(trans, extent_root, path, path->slots[0],
num_to_del);
BUG_ON(ret);
@@ -3154,11 +3164,11 @@ static int __btrfs_alloc_reserved_extent(struct btrfs_trans_handle *trans,
spin_lock(&info->delalloc_lock);
super_used = btrfs_super_bytes_used(&info->super_copy);
btrfs_set_super_bytes_used(&info->super_copy, super_used + num_bytes);
- spin_unlock(&info->delalloc_lock);
/* block accounting for root item */
root_used = btrfs_root_used(&root->root_item);
btrfs_set_root_used(&root->root_item, root_used + num_bytes);
+ spin_unlock(&info->delalloc_lock);
if (root == extent_root) {
struct pending_extent_op *extent_op;