diff options
author | Arne Jansen <sensille@gmx.net> | 2011-09-12 09:26:38 -0400 |
---|---|---|
committer | Jan Schmidt <list.btrfs@jan-o-sch.net> | 2011-12-22 10:22:27 -0500 |
commit | 66d7e7f09f77456fe68683247d77721032a00ee5 (patch) | |
tree | bbf7df3933ed47aa202d60d835864543d25df82d /fs | |
parent | c7d22a3c3cdb73d8a0151e2ccc8cf4a48c48310b (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')
-rw-r--r-- | fs/btrfs/ctree.c | 42 | ||||
-rw-r--r-- | fs/btrfs/ctree.h | 17 | ||||
-rw-r--r-- | fs/btrfs/delayed-ref.c | 50 | ||||
-rw-r--r-- | fs/btrfs/delayed-ref.h | 15 | ||||
-rw-r--r-- | fs/btrfs/disk-io.c | 3 | ||||
-rw-r--r-- | fs/btrfs/extent-tree.c | 101 | ||||
-rw-r--r-- | fs/btrfs/file.c | 10 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 2 | ||||
-rw-r--r-- | fs/btrfs/ioctl.c | 5 | ||||
-rw-r--r-- | fs/btrfs/relocation.c | 18 | ||||
-rw-r--r-- | fs/btrfs/transaction.c | 4 | ||||
-rw-r--r-- | fs/btrfs/tree-log.c | 2 |
12 files changed, 155 insertions, 114 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index dede441bdeee..0639a555e16e 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c | |||
@@ -240,7 +240,7 @@ int btrfs_copy_root(struct btrfs_trans_handle *trans, | |||
240 | 240 | ||
241 | cow = btrfs_alloc_free_block(trans, root, buf->len, 0, | 241 | cow = btrfs_alloc_free_block(trans, root, buf->len, 0, |
242 | new_root_objectid, &disk_key, level, | 242 | new_root_objectid, &disk_key, level, |
243 | buf->start, 0); | 243 | buf->start, 0, 1); |
244 | if (IS_ERR(cow)) | 244 | if (IS_ERR(cow)) |
245 | return PTR_ERR(cow); | 245 | return PTR_ERR(cow); |
246 | 246 | ||
@@ -261,9 +261,9 @@ int btrfs_copy_root(struct btrfs_trans_handle *trans, | |||
261 | 261 | ||
262 | WARN_ON(btrfs_header_generation(buf) > trans->transid); | 262 | WARN_ON(btrfs_header_generation(buf) > trans->transid); |
263 | if (new_root_objectid == BTRFS_TREE_RELOC_OBJECTID) | 263 | if (new_root_objectid == BTRFS_TREE_RELOC_OBJECTID) |
264 | ret = btrfs_inc_ref(trans, root, cow, 1); | 264 | ret = btrfs_inc_ref(trans, root, cow, 1, 1); |
265 | else | 265 | else |
266 | ret = btrfs_inc_ref(trans, root, cow, 0); | 266 | ret = btrfs_inc_ref(trans, root, cow, 0, 1); |
267 | 267 | ||
268 | if (ret) | 268 | if (ret) |
269 | return ret; | 269 | return ret; |
@@ -350,14 +350,14 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans, | |||
350 | if ((owner == root->root_key.objectid || | 350 | if ((owner == root->root_key.objectid || |
351 | root->root_key.objectid == BTRFS_TREE_RELOC_OBJECTID) && | 351 | root->root_key.objectid == BTRFS_TREE_RELOC_OBJECTID) && |
352 | !(flags & BTRFS_BLOCK_FLAG_FULL_BACKREF)) { | 352 | !(flags & BTRFS_BLOCK_FLAG_FULL_BACKREF)) { |
353 | ret = btrfs_inc_ref(trans, root, buf, 1); | 353 | ret = btrfs_inc_ref(trans, root, buf, 1, 1); |
354 | BUG_ON(ret); | 354 | BUG_ON(ret); |
355 | 355 | ||
356 | if (root->root_key.objectid == | 356 | if (root->root_key.objectid == |
357 | BTRFS_TREE_RELOC_OBJECTID) { | 357 | BTRFS_TREE_RELOC_OBJECTID) { |
358 | ret = btrfs_dec_ref(trans, root, buf, 0); | 358 | ret = btrfs_dec_ref(trans, root, buf, 0, 1); |
359 | BUG_ON(ret); | 359 | BUG_ON(ret); |
360 | ret = btrfs_inc_ref(trans, root, cow, 1); | 360 | ret = btrfs_inc_ref(trans, root, cow, 1, 1); |
361 | BUG_ON(ret); | 361 | BUG_ON(ret); |
362 | } | 362 | } |
363 | new_flags |= BTRFS_BLOCK_FLAG_FULL_BACKREF; | 363 | new_flags |= BTRFS_BLOCK_FLAG_FULL_BACKREF; |
@@ -365,9 +365,9 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans, | |||
365 | 365 | ||
366 | if (root->root_key.objectid == | 366 | if (root->root_key.objectid == |
367 | BTRFS_TREE_RELOC_OBJECTID) | 367 | BTRFS_TREE_RELOC_OBJECTID) |
368 | ret = btrfs_inc_ref(trans, root, cow, 1); | 368 | ret = btrfs_inc_ref(trans, root, cow, 1, 1); |
369 | else | 369 | else |
370 | ret = btrfs_inc_ref(trans, root, cow, 0); | 370 | ret = btrfs_inc_ref(trans, root, cow, 0, 1); |
371 | BUG_ON(ret); | 371 | BUG_ON(ret); |
372 | } | 372 | } |
373 | if (new_flags != 0) { | 373 | if (new_flags != 0) { |
@@ -381,11 +381,11 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans, | |||
381 | if (flags & BTRFS_BLOCK_FLAG_FULL_BACKREF) { | 381 | if (flags & BTRFS_BLOCK_FLAG_FULL_BACKREF) { |
382 | if (root->root_key.objectid == | 382 | if (root->root_key.objectid == |
383 | BTRFS_TREE_RELOC_OBJECTID) | 383 | BTRFS_TREE_RELOC_OBJECTID) |
384 | ret = btrfs_inc_ref(trans, root, cow, 1); | 384 | ret = btrfs_inc_ref(trans, root, cow, 1, 1); |
385 | else | 385 | else |
386 | ret = btrfs_inc_ref(trans, root, cow, 0); | 386 | ret = btrfs_inc_ref(trans, root, cow, 0, 1); |
387 | BUG_ON(ret); | 387 | BUG_ON(ret); |
388 | ret = btrfs_dec_ref(trans, root, buf, 1); | 388 | ret = btrfs_dec_ref(trans, root, buf, 1, 1); |
389 | BUG_ON(ret); | 389 | BUG_ON(ret); |
390 | } | 390 | } |
391 | clean_tree_block(trans, root, buf); | 391 | clean_tree_block(trans, root, buf); |
@@ -446,7 +446,7 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans, | |||
446 | 446 | ||
447 | cow = btrfs_alloc_free_block(trans, root, buf->len, parent_start, | 447 | cow = btrfs_alloc_free_block(trans, root, buf->len, parent_start, |
448 | root->root_key.objectid, &disk_key, | 448 | root->root_key.objectid, &disk_key, |
449 | level, search_start, empty_size); | 449 | level, search_start, empty_size, 1); |
450 | if (IS_ERR(cow)) | 450 | if (IS_ERR(cow)) |
451 | return PTR_ERR(cow); | 451 | return PTR_ERR(cow); |
452 | 452 | ||
@@ -484,7 +484,7 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans, | |||
484 | rcu_assign_pointer(root->node, cow); | 484 | rcu_assign_pointer(root->node, cow); |
485 | 485 | ||
486 | btrfs_free_tree_block(trans, root, buf, parent_start, | 486 | btrfs_free_tree_block(trans, root, buf, parent_start, |
487 | last_ref); | 487 | last_ref, 1); |
488 | free_extent_buffer(buf); | 488 | free_extent_buffer(buf); |
489 | add_root_to_dirty_list(root); | 489 | add_root_to_dirty_list(root); |
490 | } else { | 490 | } else { |
@@ -500,7 +500,7 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans, | |||
500 | trans->transid); | 500 | trans->transid); |
501 | btrfs_mark_buffer_dirty(parent); | 501 | btrfs_mark_buffer_dirty(parent); |
502 | btrfs_free_tree_block(trans, root, buf, parent_start, | 502 | btrfs_free_tree_block(trans, root, buf, parent_start, |
503 | last_ref); | 503 | last_ref, 1); |
504 | } | 504 | } |
505 | if (unlock_orig) | 505 | if (unlock_orig) |
506 | btrfs_tree_unlock(buf); | 506 | btrfs_tree_unlock(buf); |
@@ -957,7 +957,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, | |||
957 | free_extent_buffer(mid); | 957 | free_extent_buffer(mid); |
958 | 958 | ||
959 | root_sub_used(root, mid->len); | 959 | root_sub_used(root, mid->len); |
960 | btrfs_free_tree_block(trans, root, mid, 0, 1); | 960 | btrfs_free_tree_block(trans, root, mid, 0, 1, 0); |
961 | /* once for the root ptr */ | 961 | /* once for the root ptr */ |
962 | free_extent_buffer(mid); | 962 | free_extent_buffer(mid); |
963 | return 0; | 963 | return 0; |
@@ -1015,7 +1015,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, | |||
1015 | if (wret) | 1015 | if (wret) |
1016 | ret = wret; | 1016 | ret = wret; |
1017 | root_sub_used(root, right->len); | 1017 | root_sub_used(root, right->len); |
1018 | btrfs_free_tree_block(trans, root, right, 0, 1); | 1018 | btrfs_free_tree_block(trans, root, right, 0, 1, 0); |
1019 | free_extent_buffer(right); | 1019 | free_extent_buffer(right); |
1020 | right = NULL; | 1020 | right = NULL; |
1021 | } else { | 1021 | } else { |
@@ -1055,7 +1055,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, | |||
1055 | if (wret) | 1055 | if (wret) |
1056 | ret = wret; | 1056 | ret = wret; |
1057 | root_sub_used(root, mid->len); | 1057 | root_sub_used(root, mid->len); |
1058 | btrfs_free_tree_block(trans, root, mid, 0, 1); | 1058 | btrfs_free_tree_block(trans, root, mid, 0, 1, 0); |
1059 | free_extent_buffer(mid); | 1059 | free_extent_buffer(mid); |
1060 | mid = NULL; | 1060 | mid = NULL; |
1061 | } else { | 1061 | } else { |
@@ -2089,7 +2089,7 @@ static noinline int insert_new_root(struct btrfs_trans_handle *trans, | |||
2089 | 2089 | ||
2090 | c = btrfs_alloc_free_block(trans, root, root->nodesize, 0, | 2090 | c = btrfs_alloc_free_block(trans, root, root->nodesize, 0, |
2091 | root->root_key.objectid, &lower_key, | 2091 | root->root_key.objectid, &lower_key, |
2092 | level, root->node->start, 0); | 2092 | level, root->node->start, 0, 0); |
2093 | if (IS_ERR(c)) | 2093 | if (IS_ERR(c)) |
2094 | return PTR_ERR(c); | 2094 | return PTR_ERR(c); |
2095 | 2095 | ||
@@ -2216,7 +2216,7 @@ static noinline int split_node(struct btrfs_trans_handle *trans, | |||
2216 | 2216 | ||
2217 | split = btrfs_alloc_free_block(trans, root, root->nodesize, 0, | 2217 | split = btrfs_alloc_free_block(trans, root, root->nodesize, 0, |
2218 | root->root_key.objectid, | 2218 | root->root_key.objectid, |
2219 | &disk_key, level, c->start, 0); | 2219 | &disk_key, level, c->start, 0, 0); |
2220 | if (IS_ERR(split)) | 2220 | if (IS_ERR(split)) |
2221 | return PTR_ERR(split); | 2221 | return PTR_ERR(split); |
2222 | 2222 | ||
@@ -2970,7 +2970,7 @@ again: | |||
2970 | 2970 | ||
2971 | right = btrfs_alloc_free_block(trans, root, root->leafsize, 0, | 2971 | right = btrfs_alloc_free_block(trans, root, root->leafsize, 0, |
2972 | root->root_key.objectid, | 2972 | root->root_key.objectid, |
2973 | &disk_key, 0, l->start, 0); | 2973 | &disk_key, 0, l->start, 0, 0); |
2974 | if (IS_ERR(right)) | 2974 | if (IS_ERR(right)) |
2975 | return PTR_ERR(right); | 2975 | return PTR_ERR(right); |
2976 | 2976 | ||
@@ -3781,7 +3781,7 @@ static noinline int btrfs_del_leaf(struct btrfs_trans_handle *trans, | |||
3781 | 3781 | ||
3782 | root_sub_used(root, leaf->len); | 3782 | root_sub_used(root, leaf->len); |
3783 | 3783 | ||
3784 | btrfs_free_tree_block(trans, root, leaf, 0, 1); | 3784 | btrfs_free_tree_block(trans, root, leaf, 0, 1, 0); |
3785 | return 0; | 3785 | return 0; |
3786 | } | 3786 | } |
3787 | /* | 3787 | /* |
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 3e4a07b79817..543f60bddb39 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -2277,11 +2277,11 @@ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, | |||
2277 | struct btrfs_root *root, u32 blocksize, | 2277 | struct btrfs_root *root, u32 blocksize, |
2278 | u64 parent, u64 root_objectid, | 2278 | u64 parent, u64 root_objectid, |
2279 | struct btrfs_disk_key *key, int level, | 2279 | struct btrfs_disk_key *key, int level, |
2280 | u64 hint, u64 empty_size); | 2280 | u64 hint, u64 empty_size, int for_cow); |
2281 | void btrfs_free_tree_block(struct btrfs_trans_handle *trans, | 2281 | void btrfs_free_tree_block(struct btrfs_trans_handle *trans, |
2282 | struct btrfs_root *root, | 2282 | struct btrfs_root *root, |
2283 | struct extent_buffer *buf, | 2283 | struct extent_buffer *buf, |
2284 | u64 parent, int last_ref); | 2284 | u64 parent, int last_ref, int for_cow); |
2285 | struct extent_buffer *btrfs_init_new_buffer(struct btrfs_trans_handle *trans, | 2285 | struct extent_buffer *btrfs_init_new_buffer(struct btrfs_trans_handle *trans, |
2286 | struct btrfs_root *root, | 2286 | struct btrfs_root *root, |
2287 | u64 bytenr, u32 blocksize, | 2287 | u64 bytenr, u32 blocksize, |
@@ -2301,17 +2301,17 @@ int btrfs_reserve_extent(struct btrfs_trans_handle *trans, | |||
2301 | u64 search_end, struct btrfs_key *ins, | 2301 | u64 search_end, struct btrfs_key *ins, |
2302 | u64 data); | 2302 | u64 data); |
2303 | int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, | 2303 | int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, |
2304 | struct extent_buffer *buf, int full_backref); | 2304 | struct extent_buffer *buf, int full_backref, int for_cow); |
2305 | int btrfs_dec_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, | 2305 | int btrfs_dec_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, |
2306 | struct extent_buffer *buf, int full_backref); | 2306 | struct extent_buffer *buf, int full_backref, int for_cow); |
2307 | int btrfs_set_disk_extent_flags(struct btrfs_trans_handle *trans, | 2307 | int btrfs_set_disk_extent_flags(struct btrfs_trans_handle *trans, |
2308 | struct btrfs_root *root, | 2308 | struct btrfs_root *root, |
2309 | u64 bytenr, u64 num_bytes, u64 flags, | 2309 | u64 bytenr, u64 num_bytes, u64 flags, |
2310 | int is_data); | 2310 | int is_data); |
2311 | int btrfs_free_extent(struct btrfs_trans_handle *trans, | 2311 | int btrfs_free_extent(struct btrfs_trans_handle *trans, |
2312 | struct btrfs_root *root, | 2312 | struct btrfs_root *root, |
2313 | u64 bytenr, u64 num_bytes, u64 parent, | 2313 | u64 bytenr, u64 num_bytes, u64 parent, u64 root_objectid, |
2314 | u64 root_objectid, u64 owner, u64 offset); | 2314 | u64 owner, u64 offset, int for_cow); |
2315 | 2315 | ||
2316 | int btrfs_free_reserved_extent(struct btrfs_root *root, u64 start, u64 len); | 2316 | int btrfs_free_reserved_extent(struct btrfs_root *root, u64 start, u64 len); |
2317 | int btrfs_free_and_pin_reserved_extent(struct btrfs_root *root, | 2317 | int btrfs_free_and_pin_reserved_extent(struct btrfs_root *root, |
@@ -2323,7 +2323,7 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans, | |||
2323 | int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, | 2323 | int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, |
2324 | struct btrfs_root *root, | 2324 | struct btrfs_root *root, |
2325 | u64 bytenr, u64 num_bytes, u64 parent, | 2325 | u64 bytenr, u64 num_bytes, u64 parent, |
2326 | u64 root_objectid, u64 owner, u64 offset); | 2326 | u64 root_objectid, u64 owner, u64 offset, int for_cow); |
2327 | 2327 | ||
2328 | int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans, | 2328 | int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans, |
2329 | struct btrfs_root *root); | 2329 | struct btrfs_root *root); |
@@ -2492,7 +2492,8 @@ static inline int btrfs_next_item(struct btrfs_root *root, struct btrfs_path *p) | |||
2492 | int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path); | 2492 | int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path); |
2493 | int btrfs_leaf_free_space(struct btrfs_root *root, struct extent_buffer *leaf); | 2493 | int btrfs_leaf_free_space(struct btrfs_root *root, struct extent_buffer *leaf); |
2494 | void btrfs_drop_snapshot(struct btrfs_root *root, | 2494 | void btrfs_drop_snapshot(struct btrfs_root *root, |
2495 | struct btrfs_block_rsv *block_rsv, int update_ref); | 2495 | struct btrfs_block_rsv *block_rsv, int update_ref, |
2496 | int for_reloc); | ||
2496 | int btrfs_drop_subtree(struct btrfs_trans_handle *trans, | 2497 | int btrfs_drop_subtree(struct btrfs_trans_handle *trans, |
2497 | struct btrfs_root *root, | 2498 | struct btrfs_root *root, |
2498 | struct extent_buffer *node, | 2499 | struct extent_buffer *node, |
diff --git a/fs/btrfs/delayed-ref.c b/fs/btrfs/delayed-ref.c index 125cf76fcd08..3a0f0ab804f4 100644 --- a/fs/btrfs/delayed-ref.c +++ b/fs/btrfs/delayed-ref.c | |||
@@ -390,7 +390,8 @@ update_existing_head_ref(struct btrfs_delayed_ref_node *existing, | |||
390 | * this does all the dirty work in terms of maintaining the correct | 390 | * this does all the dirty work in terms of maintaining the correct |
391 | * overall modification count. | 391 | * overall modification count. |
392 | */ | 392 | */ |
393 | static noinline int add_delayed_ref_head(struct btrfs_trans_handle *trans, | 393 | static noinline int add_delayed_ref_head(struct btrfs_fs_info *fs_info, |
394 | struct btrfs_trans_handle *trans, | ||
394 | struct btrfs_delayed_ref_node *ref, | 395 | struct btrfs_delayed_ref_node *ref, |
395 | u64 bytenr, u64 num_bytes, | 396 | u64 bytenr, u64 num_bytes, |
396 | int action, int is_data) | 397 | int action, int is_data) |
@@ -468,10 +469,12 @@ static noinline int add_delayed_ref_head(struct btrfs_trans_handle *trans, | |||
468 | /* | 469 | /* |
469 | * helper to insert a delayed tree ref into the rbtree. | 470 | * helper to insert a delayed tree ref into the rbtree. |
470 | */ | 471 | */ |
471 | static noinline int add_delayed_tree_ref(struct btrfs_trans_handle *trans, | 472 | static noinline int add_delayed_tree_ref(struct btrfs_fs_info *fs_info, |
473 | struct btrfs_trans_handle *trans, | ||
472 | struct btrfs_delayed_ref_node *ref, | 474 | struct btrfs_delayed_ref_node *ref, |
473 | u64 bytenr, u64 num_bytes, u64 parent, | 475 | u64 bytenr, u64 num_bytes, u64 parent, |
474 | u64 ref_root, int level, int action) | 476 | u64 ref_root, int level, int action, |
477 | int for_cow) | ||
475 | { | 478 | { |
476 | struct btrfs_delayed_ref_node *existing; | 479 | struct btrfs_delayed_ref_node *existing; |
477 | struct btrfs_delayed_tree_ref *full_ref; | 480 | struct btrfs_delayed_tree_ref *full_ref; |
@@ -522,11 +525,12 @@ static noinline int add_delayed_tree_ref(struct btrfs_trans_handle *trans, | |||
522 | /* | 525 | /* |
523 | * helper to insert a delayed data ref into the rbtree. | 526 | * helper to insert a delayed data ref into the rbtree. |
524 | */ | 527 | */ |
525 | static noinline int add_delayed_data_ref(struct btrfs_trans_handle *trans, | 528 | static noinline int add_delayed_data_ref(struct btrfs_fs_info *fs_info, |
529 | struct btrfs_trans_handle *trans, | ||
526 | struct btrfs_delayed_ref_node *ref, | 530 | struct btrfs_delayed_ref_node *ref, |
527 | u64 bytenr, u64 num_bytes, u64 parent, | 531 | u64 bytenr, u64 num_bytes, u64 parent, |
528 | u64 ref_root, u64 owner, u64 offset, | 532 | u64 ref_root, u64 owner, u64 offset, |
529 | int action) | 533 | int action, int for_cow) |
530 | { | 534 | { |
531 | struct btrfs_delayed_ref_node *existing; | 535 | struct btrfs_delayed_ref_node *existing; |
532 | struct btrfs_delayed_data_ref *full_ref; | 536 | struct btrfs_delayed_data_ref *full_ref; |
@@ -554,6 +558,7 @@ static noinline int add_delayed_data_ref(struct btrfs_trans_handle *trans, | |||
554 | full_ref->root = ref_root; | 558 | full_ref->root = ref_root; |
555 | ref->type = BTRFS_EXTENT_DATA_REF_KEY; | 559 | ref->type = BTRFS_EXTENT_DATA_REF_KEY; |
556 | } | 560 | } |
561 | |||
557 | full_ref->objectid = owner; | 562 | full_ref->objectid = owner; |
558 | full_ref->offset = offset; | 563 | full_ref->offset = offset; |
559 | 564 | ||
@@ -580,10 +585,12 @@ static noinline int add_delayed_data_ref(struct btrfs_trans_handle *trans, | |||
580 | * to make sure the delayed ref is eventually processed before this | 585 | * to make sure the delayed ref is eventually processed before this |
581 | * transaction commits. | 586 | * transaction commits. |
582 | */ | 587 | */ |
583 | int btrfs_add_delayed_tree_ref(struct btrfs_trans_handle *trans, | 588 | int btrfs_add_delayed_tree_ref(struct btrfs_fs_info *fs_info, |
589 | struct btrfs_trans_handle *trans, | ||
584 | u64 bytenr, u64 num_bytes, u64 parent, | 590 | u64 bytenr, u64 num_bytes, u64 parent, |
585 | u64 ref_root, int level, int action, | 591 | u64 ref_root, int level, int action, |
586 | struct btrfs_delayed_extent_op *extent_op) | 592 | struct btrfs_delayed_extent_op *extent_op, |
593 | int for_cow) | ||
587 | { | 594 | { |
588 | struct btrfs_delayed_tree_ref *ref; | 595 | struct btrfs_delayed_tree_ref *ref; |
589 | struct btrfs_delayed_ref_head *head_ref; | 596 | struct btrfs_delayed_ref_head *head_ref; |
@@ -610,12 +617,13 @@ int btrfs_add_delayed_tree_ref(struct btrfs_trans_handle *trans, | |||
610 | * insert both the head node and the new ref without dropping | 617 | * insert both the head node and the new ref without dropping |
611 | * the spin lock | 618 | * the spin lock |
612 | */ | 619 | */ |
613 | ret = add_delayed_ref_head(trans, &head_ref->node, bytenr, num_bytes, | 620 | ret = add_delayed_ref_head(fs_info, trans, &head_ref->node, bytenr, |
614 | action, 0); | 621 | num_bytes, action, 0); |
615 | BUG_ON(ret); | 622 | BUG_ON(ret); |
616 | 623 | ||
617 | ret = add_delayed_tree_ref(trans, &ref->node, bytenr, num_bytes, | 624 | ret = add_delayed_tree_ref(fs_info, trans, &ref->node, bytenr, |
618 | parent, ref_root, level, action); | 625 | num_bytes, parent, ref_root, level, action, |
626 | for_cow); | ||
619 | BUG_ON(ret); | 627 | BUG_ON(ret); |
620 | spin_unlock(&delayed_refs->lock); | 628 | spin_unlock(&delayed_refs->lock); |
621 | return 0; | 629 | return 0; |
@@ -624,11 +632,13 @@ int btrfs_add_delayed_tree_ref(struct btrfs_trans_handle *trans, | |||
624 | /* | 632 | /* |
625 | * add a delayed data ref. it's similar to btrfs_add_delayed_tree_ref. | 633 | * add a delayed data ref. it's similar to btrfs_add_delayed_tree_ref. |
626 | */ | 634 | */ |
627 | int btrfs_add_delayed_data_ref(struct btrfs_trans_handle *trans, | 635 | int btrfs_add_delayed_data_ref(struct btrfs_fs_info *fs_info, |
636 | struct btrfs_trans_handle *trans, | ||
628 | u64 bytenr, u64 num_bytes, | 637 | u64 bytenr, u64 num_bytes, |
629 | u64 parent, u64 ref_root, | 638 | u64 parent, u64 ref_root, |
630 | u64 owner, u64 offset, int action, | 639 | u64 owner, u64 offset, int action, |
631 | struct btrfs_delayed_extent_op *extent_op) | 640 | struct btrfs_delayed_extent_op *extent_op, |
641 | int for_cow) | ||
632 | { | 642 | { |
633 | struct btrfs_delayed_data_ref *ref; | 643 | struct btrfs_delayed_data_ref *ref; |
634 | struct btrfs_delayed_ref_head *head_ref; | 644 | struct btrfs_delayed_ref_head *head_ref; |
@@ -655,18 +665,20 @@ int btrfs_add_delayed_data_ref(struct btrfs_trans_handle *trans, | |||
655 | * insert both the head node and the new ref without dropping | 665 | * insert both the head node and the new ref without dropping |
656 | * the spin lock | 666 | * the spin lock |
657 | */ | 667 | */ |
658 | ret = add_delayed_ref_head(trans, &head_ref->node, bytenr, num_bytes, | 668 | ret = add_delayed_ref_head(fs_info, trans, &head_ref->node, bytenr, |
659 | action, 1); | 669 | num_bytes, action, 1); |
660 | BUG_ON(ret); | 670 | BUG_ON(ret); |
661 | 671 | ||
662 | ret = add_delayed_data_ref(trans, &ref->node, bytenr, num_bytes, | 672 | ret = add_delayed_data_ref(fs_info, trans, &ref->node, bytenr, |
663 | parent, ref_root, owner, offset, action); | 673 | num_bytes, parent, ref_root, owner, offset, |
674 | action, for_cow); | ||
664 | BUG_ON(ret); | 675 | BUG_ON(ret); |
665 | spin_unlock(&delayed_refs->lock); | 676 | spin_unlock(&delayed_refs->lock); |
666 | return 0; | 677 | return 0; |
667 | } | 678 | } |
668 | 679 | ||
669 | int btrfs_add_delayed_extent_op(struct btrfs_trans_handle *trans, | 680 | int btrfs_add_delayed_extent_op(struct btrfs_fs_info *fs_info, |
681 | struct btrfs_trans_handle *trans, | ||
670 | u64 bytenr, u64 num_bytes, | 682 | u64 bytenr, u64 num_bytes, |
671 | struct btrfs_delayed_extent_op *extent_op) | 683 | struct btrfs_delayed_extent_op *extent_op) |
672 | { | 684 | { |
@@ -683,7 +695,7 @@ int btrfs_add_delayed_extent_op(struct btrfs_trans_handle *trans, | |||
683 | delayed_refs = &trans->transaction->delayed_refs; | 695 | delayed_refs = &trans->transaction->delayed_refs; |
684 | spin_lock(&delayed_refs->lock); | 696 | spin_lock(&delayed_refs->lock); |
685 | 697 | ||
686 | ret = add_delayed_ref_head(trans, &head_ref->node, bytenr, | 698 | ret = add_delayed_ref_head(fs_info, trans, &head_ref->node, bytenr, |
687 | num_bytes, BTRFS_UPDATE_DELAYED_HEAD, | 699 | num_bytes, BTRFS_UPDATE_DELAYED_HEAD, |
688 | extent_op->is_data); | 700 | extent_op->is_data); |
689 | BUG_ON(ret); | 701 | BUG_ON(ret); |
diff --git a/fs/btrfs/delayed-ref.h b/fs/btrfs/delayed-ref.h index e287e3b0eab0..8316bff18d30 100644 --- a/fs/btrfs/delayed-ref.h +++ b/fs/btrfs/delayed-ref.h | |||
@@ -151,16 +151,21 @@ static inline void btrfs_put_delayed_ref(struct btrfs_delayed_ref_node *ref) | |||
151 | } | 151 | } |
152 | } | 152 | } |
153 | 153 | ||
154 | int btrfs_add_delayed_tree_ref(struct btrfs_trans_handle *trans, | 154 | int btrfs_add_delayed_tree_ref(struct btrfs_fs_info *fs_info, |
155 | struct btrfs_trans_handle *trans, | ||
155 | u64 bytenr, u64 num_bytes, u64 parent, | 156 | u64 bytenr, u64 num_bytes, u64 parent, |
156 | u64 ref_root, int level, int action, | 157 | u64 ref_root, int level, int action, |
157 | struct btrfs_delayed_extent_op *extent_op); | 158 | struct btrfs_delayed_extent_op *extent_op, |
158 | int btrfs_add_delayed_data_ref(struct btrfs_trans_handle *trans, | 159 | int for_cow); |
160 | int btrfs_add_delayed_data_ref(struct btrfs_fs_info *fs_info, | ||
161 | struct btrfs_trans_handle *trans, | ||
159 | u64 bytenr, u64 num_bytes, | 162 | u64 bytenr, u64 num_bytes, |
160 | u64 parent, u64 ref_root, | 163 | u64 parent, u64 ref_root, |
161 | u64 owner, u64 offset, int action, | 164 | u64 owner, u64 offset, int action, |
162 | struct btrfs_delayed_extent_op *extent_op); | 165 | struct btrfs_delayed_extent_op *extent_op, |
163 | int btrfs_add_delayed_extent_op(struct btrfs_trans_handle *trans, | 166 | int for_cow); |
167 | int btrfs_add_delayed_extent_op(struct btrfs_fs_info *fs_info, | ||
168 | struct btrfs_trans_handle *trans, | ||
164 | u64 bytenr, u64 num_bytes, | 169 | u64 bytenr, u64 num_bytes, |
165 | struct btrfs_delayed_extent_op *extent_op); | 170 | struct btrfs_delayed_extent_op *extent_op); |
166 | 171 | ||
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 94abc25392f6..6f8cd17c9a9f 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -1243,7 +1243,8 @@ static struct btrfs_root *alloc_log_tree(struct btrfs_trans_handle *trans, | |||
1243 | root->ref_cows = 0; | 1243 | root->ref_cows = 0; |
1244 | 1244 | ||
1245 | leaf = btrfs_alloc_free_block(trans, root, root->leafsize, 0, | 1245 | leaf = btrfs_alloc_free_block(trans, root, root->leafsize, 0, |
1246 | BTRFS_TREE_LOG_OBJECTID, NULL, 0, 0, 0); | 1246 | BTRFS_TREE_LOG_OBJECTID, NULL, |
1247 | 0, 0, 0, 0); | ||
1247 | if (IS_ERR(leaf)) { | 1248 | if (IS_ERR(leaf)) { |
1248 | kfree(root); | 1249 | kfree(root); |
1249 | return ERR_CAST(leaf); | 1250 | return ERR_CAST(leaf); |
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, | |||
1872 | int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, | 1872 | int 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: | |||
2590 | static int __btrfs_mod_ref(struct btrfs_trans_handle *trans, | 2595 | static 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 | ||
2661 | int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, | 2667 | int 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 | ||
2667 | int btrfs_dec_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, | 2673 | int 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 | ||
2673 | static int write_one_cache_group(struct btrfs_trans_handle *trans, | 2679 | static int write_one_cache_group(struct btrfs_trans_handle *trans, |
@@ -4937,16 +4943,17 @@ out: | |||
4937 | void btrfs_free_tree_block(struct btrfs_trans_handle *trans, | 4943 | void 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 | ||
4984 | int btrfs_free_extent(struct btrfs_trans_handle *trans, | 4991 | int 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); |
6453 | out: | 6468 | out: |
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 | */ |
6535 | void btrfs_drop_snapshot(struct btrfs_root *root, | 6550 | void 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 | */ |
6709 | int btrfs_drop_subtree(struct btrfs_trans_handle *trans, | 6727 | int 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) { |
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index f2e928289600..d2b60ed6c33f 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
@@ -678,7 +678,7 @@ next_slot: | |||
678 | disk_bytenr, num_bytes, 0, | 678 | disk_bytenr, num_bytes, 0, |
679 | root->root_key.objectid, | 679 | root->root_key.objectid, |
680 | new_key.objectid, | 680 | new_key.objectid, |
681 | start - extent_offset); | 681 | start - extent_offset, 0); |
682 | BUG_ON(ret); | 682 | BUG_ON(ret); |
683 | *hint_byte = disk_bytenr; | 683 | *hint_byte = disk_bytenr; |
684 | } | 684 | } |
@@ -753,7 +753,7 @@ next_slot: | |||
753 | disk_bytenr, num_bytes, 0, | 753 | disk_bytenr, num_bytes, 0, |
754 | root->root_key.objectid, | 754 | root->root_key.objectid, |
755 | key.objectid, key.offset - | 755 | key.objectid, key.offset - |
756 | extent_offset); | 756 | extent_offset, 0); |
757 | BUG_ON(ret); | 757 | BUG_ON(ret); |
758 | inode_sub_bytes(inode, | 758 | inode_sub_bytes(inode, |
759 | extent_end - key.offset); | 759 | extent_end - key.offset); |
@@ -962,7 +962,7 @@ again: | |||
962 | 962 | ||
963 | ret = btrfs_inc_extent_ref(trans, root, bytenr, num_bytes, 0, | 963 | ret = btrfs_inc_extent_ref(trans, root, bytenr, num_bytes, 0, |
964 | root->root_key.objectid, | 964 | root->root_key.objectid, |
965 | ino, orig_offset); | 965 | ino, orig_offset, 0); |
966 | BUG_ON(ret); | 966 | BUG_ON(ret); |
967 | 967 | ||
968 | if (split == start) { | 968 | if (split == start) { |
@@ -989,7 +989,7 @@ again: | |||
989 | del_nr++; | 989 | del_nr++; |
990 | ret = btrfs_free_extent(trans, root, bytenr, num_bytes, | 990 | ret = btrfs_free_extent(trans, root, bytenr, num_bytes, |
991 | 0, root->root_key.objectid, | 991 | 0, root->root_key.objectid, |
992 | ino, orig_offset); | 992 | ino, orig_offset, 0); |
993 | BUG_ON(ret); | 993 | BUG_ON(ret); |
994 | } | 994 | } |
995 | other_start = 0; | 995 | other_start = 0; |
@@ -1006,7 +1006,7 @@ again: | |||
1006 | del_nr++; | 1006 | del_nr++; |
1007 | ret = btrfs_free_extent(trans, root, bytenr, num_bytes, | 1007 | ret = btrfs_free_extent(trans, root, bytenr, num_bytes, |
1008 | 0, root->root_key.objectid, | 1008 | 0, root->root_key.objectid, |
1009 | ino, orig_offset); | 1009 | ino, orig_offset, 0); |
1010 | BUG_ON(ret); | 1010 | BUG_ON(ret); |
1011 | } | 1011 | } |
1012 | if (del_nr == 0) { | 1012 | if (del_nr == 0) { |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index c5ccec23984c..ea819386b864 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -3139,7 +3139,7 @@ delete: | |||
3139 | ret = btrfs_free_extent(trans, root, extent_start, | 3139 | ret = btrfs_free_extent(trans, root, extent_start, |
3140 | extent_num_bytes, 0, | 3140 | extent_num_bytes, 0, |
3141 | btrfs_header_owner(leaf), | 3141 | btrfs_header_owner(leaf), |
3142 | ino, extent_offset); | 3142 | ino, extent_offset, 0); |
3143 | BUG_ON(ret); | 3143 | BUG_ON(ret); |
3144 | } | 3144 | } |
3145 | 3145 | ||
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 72d461656f60..c48f2e931ea0 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -358,7 +358,7 @@ static noinline int create_subvol(struct btrfs_root *root, | |||
358 | return PTR_ERR(trans); | 358 | return PTR_ERR(trans); |
359 | 359 | ||
360 | leaf = btrfs_alloc_free_block(trans, root, root->leafsize, | 360 | leaf = btrfs_alloc_free_block(trans, root, root->leafsize, |
361 | 0, objectid, NULL, 0, 0, 0); | 361 | 0, objectid, NULL, 0, 0, 0, 0); |
362 | if (IS_ERR(leaf)) { | 362 | if (IS_ERR(leaf)) { |
363 | ret = PTR_ERR(leaf); | 363 | ret = PTR_ERR(leaf); |
364 | goto fail; | 364 | goto fail; |
@@ -2425,7 +2425,8 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, | |||
2425 | disko, diskl, 0, | 2425 | disko, diskl, 0, |
2426 | root->root_key.objectid, | 2426 | root->root_key.objectid, |
2427 | btrfs_ino(inode), | 2427 | btrfs_ino(inode), |
2428 | new_key.offset - datao); | 2428 | new_key.offset - datao, |
2429 | 0); | ||
2429 | BUG_ON(ret); | 2430 | BUG_ON(ret); |
2430 | } | 2431 | } |
2431 | } else if (type == BTRFS_FILE_EXTENT_INLINE) { | 2432 | } else if (type == BTRFS_FILE_EXTENT_INLINE) { |
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index dff29d5e151a..8c1aae2c845d 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c | |||
@@ -1604,12 +1604,12 @@ int replace_file_extents(struct btrfs_trans_handle *trans, | |||
1604 | ret = btrfs_inc_extent_ref(trans, root, new_bytenr, | 1604 | ret = btrfs_inc_extent_ref(trans, root, new_bytenr, |
1605 | num_bytes, parent, | 1605 | num_bytes, parent, |
1606 | btrfs_header_owner(leaf), | 1606 | btrfs_header_owner(leaf), |
1607 | key.objectid, key.offset); | 1607 | key.objectid, key.offset, 1); |
1608 | BUG_ON(ret); | 1608 | BUG_ON(ret); |
1609 | 1609 | ||
1610 | ret = btrfs_free_extent(trans, root, bytenr, num_bytes, | 1610 | ret = btrfs_free_extent(trans, root, bytenr, num_bytes, |
1611 | parent, btrfs_header_owner(leaf), | 1611 | parent, btrfs_header_owner(leaf), |
1612 | key.objectid, key.offset); | 1612 | key.objectid, key.offset, 1); |
1613 | BUG_ON(ret); | 1613 | BUG_ON(ret); |
1614 | } | 1614 | } |
1615 | if (dirty) | 1615 | if (dirty) |
@@ -1778,21 +1778,23 @@ again: | |||
1778 | 1778 | ||
1779 | ret = btrfs_inc_extent_ref(trans, src, old_bytenr, blocksize, | 1779 | ret = btrfs_inc_extent_ref(trans, src, old_bytenr, blocksize, |
1780 | path->nodes[level]->start, | 1780 | path->nodes[level]->start, |
1781 | src->root_key.objectid, level - 1, 0); | 1781 | src->root_key.objectid, level - 1, 0, |
1782 | 1); | ||
1782 | BUG_ON(ret); | 1783 | BUG_ON(ret); |
1783 | ret = btrfs_inc_extent_ref(trans, dest, new_bytenr, blocksize, | 1784 | ret = btrfs_inc_extent_ref(trans, dest, new_bytenr, blocksize, |
1784 | 0, dest->root_key.objectid, level - 1, | 1785 | 0, dest->root_key.objectid, level - 1, |
1785 | 0); | 1786 | 0, 1); |
1786 | BUG_ON(ret); | 1787 | BUG_ON(ret); |
1787 | 1788 | ||
1788 | ret = btrfs_free_extent(trans, src, new_bytenr, blocksize, | 1789 | ret = btrfs_free_extent(trans, src, new_bytenr, blocksize, |
1789 | path->nodes[level]->start, | 1790 | path->nodes[level]->start, |
1790 | src->root_key.objectid, level - 1, 0); | 1791 | src->root_key.objectid, level - 1, 0, |
1792 | 1); | ||
1791 | BUG_ON(ret); | 1793 | BUG_ON(ret); |
1792 | 1794 | ||
1793 | ret = btrfs_free_extent(trans, dest, old_bytenr, blocksize, | 1795 | ret = btrfs_free_extent(trans, dest, old_bytenr, blocksize, |
1794 | 0, dest->root_key.objectid, level - 1, | 1796 | 0, dest->root_key.objectid, level - 1, |
1795 | 0); | 1797 | 0, 1); |
1796 | BUG_ON(ret); | 1798 | BUG_ON(ret); |
1797 | 1799 | ||
1798 | btrfs_unlock_up_safe(path, 0); | 1800 | btrfs_unlock_up_safe(path, 0); |
@@ -2244,7 +2246,7 @@ again: | |||
2244 | } else { | 2246 | } else { |
2245 | list_del_init(&reloc_root->root_list); | 2247 | list_del_init(&reloc_root->root_list); |
2246 | } | 2248 | } |
2247 | btrfs_drop_snapshot(reloc_root, rc->block_rsv, 0); | 2249 | btrfs_drop_snapshot(reloc_root, rc->block_rsv, 0, 1); |
2248 | } | 2250 | } |
2249 | 2251 | ||
2250 | if (found) { | 2252 | if (found) { |
@@ -2558,7 +2560,7 @@ static int do_relocation(struct btrfs_trans_handle *trans, | |||
2558 | node->eb->start, blocksize, | 2560 | node->eb->start, blocksize, |
2559 | upper->eb->start, | 2561 | upper->eb->start, |
2560 | btrfs_header_owner(upper->eb), | 2562 | btrfs_header_owner(upper->eb), |
2561 | node->level, 0); | 2563 | node->level, 0, 1); |
2562 | BUG_ON(ret); | 2564 | BUG_ON(ret); |
2563 | 2565 | ||
2564 | ret = btrfs_drop_subtree(trans, root, eb, upper->eb); | 2566 | ret = btrfs_drop_subtree(trans, root, eb, upper->eb); |
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 81376d94cd3c..a2bfedcbcabc 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
@@ -1393,9 +1393,9 @@ int btrfs_clean_old_snapshots(struct btrfs_root *root) | |||
1393 | 1393 | ||
1394 | if (btrfs_header_backref_rev(root->node) < | 1394 | if (btrfs_header_backref_rev(root->node) < |
1395 | BTRFS_MIXED_BACKREF_REV) | 1395 | BTRFS_MIXED_BACKREF_REV) |
1396 | btrfs_drop_snapshot(root, NULL, 0); | 1396 | btrfs_drop_snapshot(root, NULL, 0, 0); |
1397 | else | 1397 | else |
1398 | btrfs_drop_snapshot(root, NULL, 1); | 1398 | btrfs_drop_snapshot(root, NULL, 1, 0); |
1399 | } | 1399 | } |
1400 | return 0; | 1400 | return 0; |
1401 | } | 1401 | } |
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index f4d81c06d48f..fce7b9ec3bfa 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c | |||
@@ -589,7 +589,7 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans, | |||
589 | ret = btrfs_inc_extent_ref(trans, root, | 589 | ret = btrfs_inc_extent_ref(trans, root, |
590 | ins.objectid, ins.offset, | 590 | ins.objectid, ins.offset, |
591 | 0, root->root_key.objectid, | 591 | 0, root->root_key.objectid, |
592 | key->objectid, offset); | 592 | key->objectid, offset, 0); |
593 | BUG_ON(ret); | 593 | BUG_ON(ret); |
594 | } else { | 594 | } else { |
595 | /* | 595 | /* |