diff options
-rw-r--r-- | fs/btrfs/ctree.c | 31 | ||||
-rw-r--r-- | fs/btrfs/ctree.h | 4 | ||||
-rw-r--r-- | fs/btrfs/extent-tree.c | 31 | ||||
-rw-r--r-- | fs/btrfs/ioctl.c | 2 | ||||
-rw-r--r-- | fs/btrfs/transaction.c | 6 |
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); |
1985 | int 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); | ||
1985 | struct extent_buffer *btrfs_init_new_buffer(struct btrfs_trans_handle *trans, | 1989 | struct 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 | ||
4044 | int 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 | |||
4052 | static u64 stripe_align(struct btrfs_root *root, u64 val) | 4059 | static 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 | } |