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/btrfs/delayed-ref.c | |
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/btrfs/delayed-ref.c')
-rw-r--r-- | fs/btrfs/delayed-ref.c | 50 |
1 files changed, 31 insertions, 19 deletions
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); |