aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
authorYan, Zheng <zheng.yan@oracle.com>2009-11-12 04:36:50 -0500
committerChris Mason <chris.mason@oracle.com>2009-12-17 12:33:35 -0500
commit86b9f2eca5e0984145e3c7698a7cd6dd65c2a93f (patch)
tree75dd0a52848b6f5396023f811f1a602f62b9d34e /fs/btrfs
parent55ef68990029fcd8d04d42fc184aa7fb18cf309e (diff)
Btrfs: Fix per root used space accounting
The bytes_used field in root item was originally planned to trace the amount of used data and tree blocks. But it never worked right since we can't trace freeing of data accurately. This patch changes it to only trace the amount of tree blocks. Signed-off-by: Yan Zheng <zheng.yan@oracle.com> Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs')
-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 }