aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/extent-tree.c
diff options
context:
space:
mode:
authorArne Jansen <sensille@gmx.net>2011-09-12 09:26:38 -0400
committerJan Schmidt <list.btrfs@jan-o-sch.net>2011-12-22 10:22:27 -0500
commit66d7e7f09f77456fe68683247d77721032a00ee5 (patch)
treebbf7df3933ed47aa202d60d835864543d25df82d /fs/btrfs/extent-tree.c
parentc7d22a3c3cdb73d8a0151e2ccc8cf4a48c48310b (diff)
Btrfs: mark delayed refs as for cow
Add a for_cow parameter to add_delayed_*_ref and pass the appropriate value from every call site. The for_cow parameter will later on be used to determine if a ref will change anything with respect to qgroups. Delayed refs coming from relocation are always counted as for_cow, as they don't change subvol quota. Also pass in the fs_info for later use. btrfs_find_all_roots() will use this as an optimization, as changes that are for_cow will not change anything with respect to which root points to a certain leaf. Thus, we don't need to add the current sequence number to those delayed refs. Signed-off-by: Arne Jansen <sensille@gmx.net> Signed-off-by: Jan Schmidt <list.btrfs@jan-o-sch.net>
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r--fs/btrfs/extent-tree.c101
1 files changed, 60 insertions, 41 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 813c6bb96c9a..dc8b9a834596 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -1872,20 +1872,24 @@ static int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr,
1872int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, 1872int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
1873 struct btrfs_root *root, 1873 struct btrfs_root *root,
1874 u64 bytenr, u64 num_bytes, u64 parent, 1874 u64 bytenr, u64 num_bytes, u64 parent,
1875 u64 root_objectid, u64 owner, u64 offset) 1875 u64 root_objectid, u64 owner, u64 offset, int for_cow)
1876{ 1876{
1877 int ret; 1877 int ret;
1878 struct btrfs_fs_info *fs_info = root->fs_info;
1879
1878 BUG_ON(owner < BTRFS_FIRST_FREE_OBJECTID && 1880 BUG_ON(owner < BTRFS_FIRST_FREE_OBJECTID &&
1879 root_objectid == BTRFS_TREE_LOG_OBJECTID); 1881 root_objectid == BTRFS_TREE_LOG_OBJECTID);
1880 1882
1881 if (owner < BTRFS_FIRST_FREE_OBJECTID) { 1883 if (owner < BTRFS_FIRST_FREE_OBJECTID) {
1882 ret = btrfs_add_delayed_tree_ref(trans, bytenr, num_bytes, 1884 ret = btrfs_add_delayed_tree_ref(fs_info, trans, bytenr,
1885 num_bytes,
1883 parent, root_objectid, (int)owner, 1886 parent, root_objectid, (int)owner,
1884 BTRFS_ADD_DELAYED_REF, NULL); 1887 BTRFS_ADD_DELAYED_REF, NULL, for_cow);
1885 } else { 1888 } else {
1886 ret = btrfs_add_delayed_data_ref(trans, bytenr, num_bytes, 1889 ret = btrfs_add_delayed_data_ref(fs_info, trans, bytenr,
1890 num_bytes,
1887 parent, root_objectid, owner, offset, 1891 parent, root_objectid, owner, offset,
1888 BTRFS_ADD_DELAYED_REF, NULL); 1892 BTRFS_ADD_DELAYED_REF, NULL, for_cow);
1889 } 1893 }
1890 return ret; 1894 return ret;
1891} 1895}
@@ -2405,7 +2409,8 @@ int btrfs_set_disk_extent_flags(struct btrfs_trans_handle *trans,
2405 extent_op->update_key = 0; 2409 extent_op->update_key = 0;
2406 extent_op->is_data = is_data ? 1 : 0; 2410 extent_op->is_data = is_data ? 1 : 0;
2407 2411
2408 ret = btrfs_add_delayed_extent_op(trans, bytenr, num_bytes, extent_op); 2412 ret = btrfs_add_delayed_extent_op(root->fs_info, trans, bytenr,
2413 num_bytes, extent_op);
2409 if (ret) 2414 if (ret)
2410 kfree(extent_op); 2415 kfree(extent_op);
2411 return ret; 2416 return ret;
@@ -2590,7 +2595,7 @@ out:
2590static int __btrfs_mod_ref(struct btrfs_trans_handle *trans, 2595static int __btrfs_mod_ref(struct btrfs_trans_handle *trans,
2591 struct btrfs_root *root, 2596 struct btrfs_root *root,
2592 struct extent_buffer *buf, 2597 struct extent_buffer *buf,
2593 int full_backref, int inc) 2598 int full_backref, int inc, int for_cow)
2594{ 2599{
2595 u64 bytenr; 2600 u64 bytenr;
2596 u64 num_bytes; 2601 u64 num_bytes;
@@ -2603,7 +2608,7 @@ static int __btrfs_mod_ref(struct btrfs_trans_handle *trans,
2603 int level; 2608 int level;
2604 int ret = 0; 2609 int ret = 0;
2605 int (*process_func)(struct btrfs_trans_handle *, struct btrfs_root *, 2610 int (*process_func)(struct btrfs_trans_handle *, struct btrfs_root *,
2606 u64, u64, u64, u64, u64, u64); 2611 u64, u64, u64, u64, u64, u64, int);
2607 2612
2608 ref_root = btrfs_header_owner(buf); 2613 ref_root = btrfs_header_owner(buf);
2609 nritems = btrfs_header_nritems(buf); 2614 nritems = btrfs_header_nritems(buf);
@@ -2640,14 +2645,15 @@ static int __btrfs_mod_ref(struct btrfs_trans_handle *trans,
2640 key.offset -= btrfs_file_extent_offset(buf, fi); 2645 key.offset -= btrfs_file_extent_offset(buf, fi);
2641 ret = process_func(trans, root, bytenr, num_bytes, 2646 ret = process_func(trans, root, bytenr, num_bytes,
2642 parent, ref_root, key.objectid, 2647 parent, ref_root, key.objectid,
2643 key.offset); 2648 key.offset, for_cow);
2644 if (ret) 2649 if (ret)
2645 goto fail; 2650 goto fail;
2646 } else { 2651 } else {
2647 bytenr = btrfs_node_blockptr(buf, i); 2652 bytenr = btrfs_node_blockptr(buf, i);
2648 num_bytes = btrfs_level_size(root, level - 1); 2653 num_bytes = btrfs_level_size(root, level - 1);
2649 ret = process_func(trans, root, bytenr, num_bytes, 2654 ret = process_func(trans, root, bytenr, num_bytes,
2650 parent, ref_root, level - 1, 0); 2655 parent, ref_root, level - 1, 0,
2656 for_cow);
2651 if (ret) 2657 if (ret)
2652 goto fail; 2658 goto fail;
2653 } 2659 }
@@ -2659,15 +2665,15 @@ fail:
2659} 2665}
2660 2666
2661int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, 2667int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root,
2662 struct extent_buffer *buf, int full_backref) 2668 struct extent_buffer *buf, int full_backref, int for_cow)
2663{ 2669{
2664 return __btrfs_mod_ref(trans, root, buf, full_backref, 1); 2670 return __btrfs_mod_ref(trans, root, buf, full_backref, 1, for_cow);
2665} 2671}
2666 2672
2667int btrfs_dec_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, 2673int btrfs_dec_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root,
2668 struct extent_buffer *buf, int full_backref) 2674 struct extent_buffer *buf, int full_backref, int for_cow)
2669{ 2675{
2670 return __btrfs_mod_ref(trans, root, buf, full_backref, 0); 2676 return __btrfs_mod_ref(trans, root, buf, full_backref, 0, for_cow);
2671} 2677}
2672 2678
2673static int write_one_cache_group(struct btrfs_trans_handle *trans, 2679static int write_one_cache_group(struct btrfs_trans_handle *trans,
@@ -4937,16 +4943,17 @@ out:
4937void btrfs_free_tree_block(struct btrfs_trans_handle *trans, 4943void btrfs_free_tree_block(struct btrfs_trans_handle *trans,
4938 struct btrfs_root *root, 4944 struct btrfs_root *root,
4939 struct extent_buffer *buf, 4945 struct extent_buffer *buf,
4940 u64 parent, int last_ref) 4946 u64 parent, int last_ref, int for_cow)
4941{ 4947{
4942 struct btrfs_block_group_cache *cache = NULL; 4948 struct btrfs_block_group_cache *cache = NULL;
4943 int ret; 4949 int ret;
4944 4950
4945 if (root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID) { 4951 if (root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID) {
4946 ret = btrfs_add_delayed_tree_ref(trans, buf->start, buf->len, 4952 ret = btrfs_add_delayed_tree_ref(root->fs_info, trans,
4947 parent, root->root_key.objectid, 4953 buf->start, buf->len,
4948 btrfs_header_level(buf), 4954 parent, root->root_key.objectid,
4949 BTRFS_DROP_DELAYED_REF, NULL); 4955 btrfs_header_level(buf),
4956 BTRFS_DROP_DELAYED_REF, NULL, for_cow);
4950 BUG_ON(ret); 4957 BUG_ON(ret);
4951 } 4958 }
4952 4959
@@ -4981,12 +4988,12 @@ out:
4981 btrfs_put_block_group(cache); 4988 btrfs_put_block_group(cache);
4982} 4989}
4983 4990
4984int btrfs_free_extent(struct btrfs_trans_handle *trans, 4991int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root *root,
4985 struct btrfs_root *root, 4992 u64 bytenr, u64 num_bytes, u64 parent, u64 root_objectid,
4986 u64 bytenr, u64 num_bytes, u64 parent, 4993 u64 owner, u64 offset, int for_cow)
4987 u64 root_objectid, u64 owner, u64 offset)
4988{ 4994{
4989 int ret; 4995 int ret;
4996 struct btrfs_fs_info *fs_info = root->fs_info;
4990 4997
4991 /* 4998 /*
4992 * tree log blocks never actually go into the extent allocation 4999 * tree log blocks never actually go into the extent allocation
@@ -4998,14 +5005,17 @@ int btrfs_free_extent(struct btrfs_trans_handle *trans,
4998 btrfs_pin_extent(root, bytenr, num_bytes, 1); 5005 btrfs_pin_extent(root, bytenr, num_bytes, 1);
4999 ret = 0; 5006 ret = 0;
5000 } else if (owner < BTRFS_FIRST_FREE_OBJECTID) { 5007 } else if (owner < BTRFS_FIRST_FREE_OBJECTID) {
5001 ret = btrfs_add_delayed_tree_ref(trans, bytenr, num_bytes, 5008 ret = btrfs_add_delayed_tree_ref(fs_info, trans, bytenr,
5009 num_bytes,
5002 parent, root_objectid, (int)owner, 5010 parent, root_objectid, (int)owner,
5003 BTRFS_DROP_DELAYED_REF, NULL); 5011 BTRFS_DROP_DELAYED_REF, NULL, for_cow);
5004 BUG_ON(ret); 5012 BUG_ON(ret);
5005 } else { 5013 } else {
5006 ret = btrfs_add_delayed_data_ref(trans, bytenr, num_bytes, 5014 ret = btrfs_add_delayed_data_ref(fs_info, trans, bytenr,
5007 parent, root_objectid, owner, 5015 num_bytes,
5008 offset, BTRFS_DROP_DELAYED_REF, NULL); 5016 parent, root_objectid, owner,
5017 offset, BTRFS_DROP_DELAYED_REF,
5018 NULL, for_cow);
5009 BUG_ON(ret); 5019 BUG_ON(ret);
5010 } 5020 }
5011 return ret; 5021 return ret;
@@ -5826,9 +5836,10 @@ int btrfs_alloc_reserved_file_extent(struct btrfs_trans_handle *trans,
5826 5836
5827 BUG_ON(root_objectid == BTRFS_TREE_LOG_OBJECTID); 5837 BUG_ON(root_objectid == BTRFS_TREE_LOG_OBJECTID);
5828 5838
5829 ret = btrfs_add_delayed_data_ref(trans, ins->objectid, ins->offset, 5839 ret = btrfs_add_delayed_data_ref(root->fs_info, trans, ins->objectid,
5830 0, root_objectid, owner, offset, 5840 ins->offset, 0,
5831 BTRFS_ADD_DELAYED_EXTENT, NULL); 5841 root_objectid, owner, offset,
5842 BTRFS_ADD_DELAYED_EXTENT, NULL, 0);
5832 return ret; 5843 return ret;
5833} 5844}
5834 5845
@@ -5998,7 +6009,7 @@ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans,
5998 struct btrfs_root *root, u32 blocksize, 6009 struct btrfs_root *root, u32 blocksize,
5999 u64 parent, u64 root_objectid, 6010 u64 parent, u64 root_objectid,
6000 struct btrfs_disk_key *key, int level, 6011 struct btrfs_disk_key *key, int level,
6001 u64 hint, u64 empty_size) 6012 u64 hint, u64 empty_size, int for_cow)
6002{ 6013{
6003 struct btrfs_key ins; 6014 struct btrfs_key ins;
6004 struct btrfs_block_rsv *block_rsv; 6015 struct btrfs_block_rsv *block_rsv;
@@ -6042,10 +6053,11 @@ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans,
6042 extent_op->update_flags = 1; 6053 extent_op->update_flags = 1;
6043 extent_op->is_data = 0; 6054 extent_op->is_data = 0;
6044 6055
6045 ret = btrfs_add_delayed_tree_ref(trans, ins.objectid, 6056 ret = btrfs_add_delayed_tree_ref(root->fs_info, trans,
6057 ins.objectid,
6046 ins.offset, parent, root_objectid, 6058 ins.offset, parent, root_objectid,
6047 level, BTRFS_ADD_DELAYED_EXTENT, 6059 level, BTRFS_ADD_DELAYED_EXTENT,
6048 extent_op); 6060 extent_op, for_cow);
6049 BUG_ON(ret); 6061 BUG_ON(ret);
6050 } 6062 }
6051 return buf; 6063 return buf;
@@ -6062,6 +6074,7 @@ struct walk_control {
6062 int keep_locks; 6074 int keep_locks;
6063 int reada_slot; 6075 int reada_slot;
6064 int reada_count; 6076 int reada_count;
6077 int for_reloc;
6065}; 6078};
6066 6079
6067#define DROP_REFERENCE 1 6080#define DROP_REFERENCE 1
@@ -6200,9 +6213,9 @@ static noinline int walk_down_proc(struct btrfs_trans_handle *trans,
6200 /* wc->stage == UPDATE_BACKREF */ 6213 /* wc->stage == UPDATE_BACKREF */
6201 if (!(wc->flags[level] & flag)) { 6214 if (!(wc->flags[level] & flag)) {
6202 BUG_ON(!path->locks[level]); 6215 BUG_ON(!path->locks[level]);
6203 ret = btrfs_inc_ref(trans, root, eb, 1); 6216 ret = btrfs_inc_ref(trans, root, eb, 1, wc->for_reloc);
6204 BUG_ON(ret); 6217 BUG_ON(ret);
6205 ret = btrfs_dec_ref(trans, root, eb, 0); 6218 ret = btrfs_dec_ref(trans, root, eb, 0, wc->for_reloc);
6206 BUG_ON(ret); 6219 BUG_ON(ret);
6207 ret = btrfs_set_disk_extent_flags(trans, root, eb->start, 6220 ret = btrfs_set_disk_extent_flags(trans, root, eb->start,
6208 eb->len, flag, 0); 6221 eb->len, flag, 0);
@@ -6346,7 +6359,7 @@ skip:
6346 } 6359 }
6347 6360
6348 ret = btrfs_free_extent(trans, root, bytenr, blocksize, parent, 6361 ret = btrfs_free_extent(trans, root, bytenr, blocksize, parent,
6349 root->root_key.objectid, level - 1, 0); 6362 root->root_key.objectid, level - 1, 0, 0);
6350 BUG_ON(ret); 6363 BUG_ON(ret);
6351 } 6364 }
6352 btrfs_tree_unlock(next); 6365 btrfs_tree_unlock(next);
@@ -6420,9 +6433,11 @@ static noinline int walk_up_proc(struct btrfs_trans_handle *trans,
6420 if (wc->refs[level] == 1) { 6433 if (wc->refs[level] == 1) {
6421 if (level == 0) { 6434 if (level == 0) {
6422 if (wc->flags[level] & BTRFS_BLOCK_FLAG_FULL_BACKREF) 6435 if (wc->flags[level] & BTRFS_BLOCK_FLAG_FULL_BACKREF)
6423 ret = btrfs_dec_ref(trans, root, eb, 1); 6436 ret = btrfs_dec_ref(trans, root, eb, 1,
6437 wc->for_reloc);
6424 else 6438 else
6425 ret = btrfs_dec_ref(trans, root, eb, 0); 6439 ret = btrfs_dec_ref(trans, root, eb, 0,
6440 wc->for_reloc);
6426 BUG_ON(ret); 6441 BUG_ON(ret);
6427 } 6442 }
6428 /* make block locked assertion in clean_tree_block happy */ 6443 /* make block locked assertion in clean_tree_block happy */
@@ -6449,7 +6464,7 @@ static noinline int walk_up_proc(struct btrfs_trans_handle *trans,
6449 btrfs_header_owner(path->nodes[level + 1])); 6464 btrfs_header_owner(path->nodes[level + 1]));
6450 } 6465 }
6451 6466
6452 btrfs_free_tree_block(trans, root, eb, parent, wc->refs[level] == 1); 6467 btrfs_free_tree_block(trans, root, eb, parent, wc->refs[level] == 1, 0);
6453out: 6468out:
6454 wc->refs[level] = 0; 6469 wc->refs[level] = 0;
6455 wc->flags[level] = 0; 6470 wc->flags[level] = 0;
@@ -6533,7 +6548,8 @@ static noinline int walk_up_tree(struct btrfs_trans_handle *trans,
6533 * blocks are properly updated. 6548 * blocks are properly updated.
6534 */ 6549 */
6535void btrfs_drop_snapshot(struct btrfs_root *root, 6550void btrfs_drop_snapshot(struct btrfs_root *root,
6536 struct btrfs_block_rsv *block_rsv, int update_ref) 6551 struct btrfs_block_rsv *block_rsv, int update_ref,
6552 int for_reloc)
6537{ 6553{
6538 struct btrfs_path *path; 6554 struct btrfs_path *path;
6539 struct btrfs_trans_handle *trans; 6555 struct btrfs_trans_handle *trans;
@@ -6621,6 +6637,7 @@ void btrfs_drop_snapshot(struct btrfs_root *root,
6621 wc->stage = DROP_REFERENCE; 6637 wc->stage = DROP_REFERENCE;
6622 wc->update_ref = update_ref; 6638 wc->update_ref = update_ref;
6623 wc->keep_locks = 0; 6639 wc->keep_locks = 0;
6640 wc->for_reloc = for_reloc;
6624 wc->reada_count = BTRFS_NODEPTRS_PER_BLOCK(root); 6641 wc->reada_count = BTRFS_NODEPTRS_PER_BLOCK(root);
6625 6642
6626 while (1) { 6643 while (1) {
@@ -6705,6 +6722,7 @@ out:
6705 * drop subtree rooted at tree block 'node'. 6722 * drop subtree rooted at tree block 'node'.
6706 * 6723 *
6707 * NOTE: this function will unlock and release tree block 'node' 6724 * NOTE: this function will unlock and release tree block 'node'
6725 * only used by relocation code
6708 */ 6726 */
6709int btrfs_drop_subtree(struct btrfs_trans_handle *trans, 6727int btrfs_drop_subtree(struct btrfs_trans_handle *trans,
6710 struct btrfs_root *root, 6728 struct btrfs_root *root,
@@ -6749,6 +6767,7 @@ int btrfs_drop_subtree(struct btrfs_trans_handle *trans,
6749 wc->stage = DROP_REFERENCE; 6767 wc->stage = DROP_REFERENCE;
6750 wc->update_ref = 0; 6768 wc->update_ref = 0;
6751 wc->keep_locks = 1; 6769 wc->keep_locks = 1;
6770 wc->for_reloc = 1;
6752 wc->reada_count = BTRFS_NODEPTRS_PER_BLOCK(root); 6771 wc->reada_count = BTRFS_NODEPTRS_PER_BLOCK(root);
6753 6772
6754 while (1) { 6773 while (1) {