aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/ctree.c31
-rw-r--r--fs/btrfs/ctree.h4
-rw-r--r--fs/btrfs/extent-tree.c31
-rw-r--r--fs/btrfs/ioctl.c2
-rw-r--r--fs/btrfs/transaction.c6
5 files changed, 47 insertions, 27 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index 9d4ba3470c17..c4bc570a396e 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -456,9 +456,8 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans,
456 extent_buffer_get(cow); 456 extent_buffer_get(cow);
457 spin_unlock(&root->node_lock); 457 spin_unlock(&root->node_lock);
458 458
459 btrfs_free_extent(trans, root, buf->start, buf->len, 459 btrfs_free_tree_block(trans, root, buf->start, buf->len,
460 parent_start, root->root_key.objectid, 460 parent_start, root->root_key.objectid, level);
461 level, 0);
462 free_extent_buffer(buf); 461 free_extent_buffer(buf);
463 add_root_to_dirty_list(root); 462 add_root_to_dirty_list(root);
464 } else { 463 } else {
@@ -473,9 +472,8 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans,
473 btrfs_set_node_ptr_generation(parent, parent_slot, 472 btrfs_set_node_ptr_generation(parent, parent_slot,
474 trans->transid); 473 trans->transid);
475 btrfs_mark_buffer_dirty(parent); 474 btrfs_mark_buffer_dirty(parent);
476 btrfs_free_extent(trans, root, buf->start, buf->len, 475 btrfs_free_tree_block(trans, root, buf->start, buf->len,
477 parent_start, root->root_key.objectid, 476 parent_start, root->root_key.objectid, level);
478 level, 0);
479 } 477 }
480 if (unlock_orig) 478 if (unlock_orig)
481 btrfs_tree_unlock(buf); 479 btrfs_tree_unlock(buf);
@@ -1035,8 +1033,8 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
1035 btrfs_tree_unlock(mid); 1033 btrfs_tree_unlock(mid);
1036 /* once for the path */ 1034 /* once for the path */
1037 free_extent_buffer(mid); 1035 free_extent_buffer(mid);
1038 ret = btrfs_free_extent(trans, root, mid->start, mid->len, 1036 ret = btrfs_free_tree_block(trans, root, mid->start, mid->len,
1039 0, root->root_key.objectid, level, 1); 1037 0, root->root_key.objectid, level);
1040 /* once for the root ptr */ 1038 /* once for the root ptr */
1041 free_extent_buffer(mid); 1039 free_extent_buffer(mid);
1042 return ret; 1040 return ret;
@@ -1100,10 +1098,10 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
1100 1); 1098 1);
1101 if (wret) 1099 if (wret)
1102 ret = wret; 1100 ret = wret;
1103 wret = btrfs_free_extent(trans, root, bytenr, 1101 wret = btrfs_free_tree_block(trans, root,
1104 blocksize, 0, 1102 bytenr, blocksize, 0,
1105 root->root_key.objectid, 1103 root->root_key.objectid,
1106 level, 0); 1104 level);
1107 if (wret) 1105 if (wret)
1108 ret = wret; 1106 ret = wret;
1109 } else { 1107 } else {
@@ -1148,9 +1146,8 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
1148 wret = del_ptr(trans, root, path, level + 1, pslot); 1146 wret = del_ptr(trans, root, path, level + 1, pslot);
1149 if (wret) 1147 if (wret)
1150 ret = wret; 1148 ret = wret;
1151 wret = btrfs_free_extent(trans, root, bytenr, blocksize, 1149 wret = btrfs_free_tree_block(trans, root, bytenr, blocksize,
1152 0, root->root_key.objectid, 1150 0, root->root_key.objectid, level);
1153 level, 0);
1154 if (wret) 1151 if (wret)
1155 ret = wret; 1152 ret = wret;
1156 } else { 1153 } else {
@@ -3794,8 +3791,8 @@ static noinline int btrfs_del_leaf(struct btrfs_trans_handle *trans,
3794 */ 3791 */
3795 btrfs_unlock_up_safe(path, 0); 3792 btrfs_unlock_up_safe(path, 0);
3796 3793
3797 ret = btrfs_free_extent(trans, root, leaf->start, leaf->len, 3794 ret = btrfs_free_tree_block(trans, root, leaf->start, leaf->len,
3798 0, root->root_key.objectid, 0, 0); 3795 0, root->root_key.objectid, 0);
3799 return ret; 3796 return ret;
3800} 3797}
3801/* 3798/*
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 1983c889bb1c..9f806dd04c27 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -1982,6 +1982,10 @@ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans,
1982 u64 parent, u64 root_objectid, 1982 u64 parent, u64 root_objectid,
1983 struct btrfs_disk_key *key, int level, 1983 struct btrfs_disk_key *key, int level,
1984 u64 hint, u64 empty_size); 1984 u64 hint, u64 empty_size);
1985int btrfs_free_tree_block(struct btrfs_trans_handle *trans,
1986 struct btrfs_root *root,
1987 u64 bytenr, u32 blocksize,
1988 u64 parent, u64 root_objectid, int level);
1985struct extent_buffer *btrfs_init_new_buffer(struct btrfs_trans_handle *trans, 1989struct extent_buffer *btrfs_init_new_buffer(struct btrfs_trans_handle *trans,
1986 struct btrfs_root *root, 1990 struct btrfs_root *root,
1987 u64 bytenr, u32 blocksize, 1991 u64 bytenr, u32 blocksize,
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index fcdccfa46004..44d7a322ec28 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -3454,14 +3454,6 @@ static int update_block_group(struct btrfs_trans_handle *trans,
3454 else 3454 else
3455 old_val -= num_bytes; 3455 old_val -= num_bytes;
3456 btrfs_set_super_bytes_used(&info->super_copy, old_val); 3456 btrfs_set_super_bytes_used(&info->super_copy, old_val);
3457
3458 /* block accounting for root item */
3459 old_val = btrfs_root_used(&root->root_item);
3460 if (alloc)
3461 old_val += num_bytes;
3462 else
3463 old_val -= num_bytes;
3464 btrfs_set_root_used(&root->root_item, old_val);
3465 spin_unlock(&info->delalloc_lock); 3457 spin_unlock(&info->delalloc_lock);
3466 3458
3467 while (total) { 3459 while (total) {
@@ -4049,6 +4041,21 @@ int btrfs_free_extent(struct btrfs_trans_handle *trans,
4049 return ret; 4041 return ret;
4050} 4042}
4051 4043
4044int btrfs_free_tree_block(struct btrfs_trans_handle *trans,
4045 struct btrfs_root *root,
4046 u64 bytenr, u32 blocksize,
4047 u64 parent, u64 root_objectid, int level)
4048{
4049 u64 used;
4050 spin_lock(&root->node_lock);
4051 used = btrfs_root_used(&root->root_item) - blocksize;
4052 btrfs_set_root_used(&root->root_item, used);
4053 spin_unlock(&root->node_lock);
4054
4055 return btrfs_free_extent(trans, root, bytenr, blocksize,
4056 parent, root_objectid, level, 0);
4057}
4058
4052static u64 stripe_align(struct btrfs_root *root, u64 val) 4059static u64 stripe_align(struct btrfs_root *root, u64 val)
4053{ 4060{
4054 u64 mask = ((u64)root->stripesize - 1); 4061 u64 mask = ((u64)root->stripesize - 1);
@@ -4897,6 +4904,14 @@ static int alloc_tree_block(struct btrfs_trans_handle *trans,
4897 extent_op); 4904 extent_op);
4898 BUG_ON(ret); 4905 BUG_ON(ret);
4899 } 4906 }
4907
4908 if (root_objectid == root->root_key.objectid) {
4909 u64 used;
4910 spin_lock(&root->node_lock);
4911 used = btrfs_root_used(&root->root_item) + num_bytes;
4912 btrfs_set_root_used(&root->root_item, used);
4913 spin_unlock(&root->node_lock);
4914 }
4900 return ret; 4915 return ret;
4901} 4916}
4902 4917
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 3d6b33871afe..645a17927a8f 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -289,7 +289,7 @@ static noinline int create_subvol(struct btrfs_root *root,
289 btrfs_set_root_generation(&root_item, trans->transid); 289 btrfs_set_root_generation(&root_item, trans->transid);
290 btrfs_set_root_level(&root_item, 0); 290 btrfs_set_root_level(&root_item, 0);
291 btrfs_set_root_refs(&root_item, 1); 291 btrfs_set_root_refs(&root_item, 1);
292 btrfs_set_root_used(&root_item, 0); 292 btrfs_set_root_used(&root_item, leaf->len);
293 btrfs_set_root_last_snapshot(&root_item, 0); 293 btrfs_set_root_last_snapshot(&root_item, 0);
294 294
295 memset(&root_item.drop_progress, 0, sizeof(root_item.drop_progress)); 295 memset(&root_item.drop_progress, 0, sizeof(root_item.drop_progress));
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 75b31caade29..b2acc79f1b34 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -501,13 +501,16 @@ static int update_cowonly_root(struct btrfs_trans_handle *trans,
501{ 501{
502 int ret; 502 int ret;
503 u64 old_root_bytenr; 503 u64 old_root_bytenr;
504 u64 old_root_used;
504 struct btrfs_root *tree_root = root->fs_info->tree_root; 505 struct btrfs_root *tree_root = root->fs_info->tree_root;
505 506
507 old_root_used = btrfs_root_used(&root->root_item);
506 btrfs_write_dirty_block_groups(trans, root); 508 btrfs_write_dirty_block_groups(trans, root);
507 509
508 while (1) { 510 while (1) {
509 old_root_bytenr = btrfs_root_bytenr(&root->root_item); 511 old_root_bytenr = btrfs_root_bytenr(&root->root_item);
510 if (old_root_bytenr == root->node->start) 512 if (old_root_bytenr == root->node->start &&
513 old_root_used == btrfs_root_used(&root->root_item))
511 break; 514 break;
512 515
513 btrfs_set_root_node(&root->root_item, root->node); 516 btrfs_set_root_node(&root->root_item, root->node);
@@ -516,6 +519,7 @@ static int update_cowonly_root(struct btrfs_trans_handle *trans,
516 &root->root_item); 519 &root->root_item);
517 BUG_ON(ret); 520 BUG_ON(ret);
518 521
522 old_root_used = btrfs_root_used(&root->root_item);
519 ret = btrfs_write_dirty_block_groups(trans, root); 523 ret = btrfs_write_dirty_block_groups(trans, root);
520 BUG_ON(ret); 524 BUG_ON(ret);
521 } 525 }