Btrfs: properly update block accounting for metadata
authorYan Zheng <zheng.yan@oracle.com>
Fri, 19 Dec 2008 15:58:46 +0000 (10:58 -0500)
committerChris Mason <chris.mason@oracle.com>
Fri, 19 Dec 2008 15:58:46 +0000 (10:58 -0500)
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>
fs/btrfs/extent-tree.c

index 9ef2a2be2686714518fc839d382f8f4249f35b96..274bb91efa22dd407a0fee85181c48a26f5e86a9 100644 (file)
@@ -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;