diff options
Diffstat (limited to 'fs/btrfs/transaction.c')
-rw-r--r-- | fs/btrfs/transaction.c | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 3aafbde8b637..1c54e2eb74ab 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
@@ -697,6 +697,7 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans, | |||
697 | unsigned long cur = trans->delayed_ref_updates; | 697 | unsigned long cur = trans->delayed_ref_updates; |
698 | int lock = (trans->type != TRANS_JOIN_NOLOCK); | 698 | int lock = (trans->type != TRANS_JOIN_NOLOCK); |
699 | int err = 0; | 699 | int err = 0; |
700 | int must_run_delayed_refs = 0; | ||
700 | 701 | ||
701 | if (trans->use_count > 1) { | 702 | if (trans->use_count > 1) { |
702 | trans->use_count--; | 703 | trans->use_count--; |
@@ -711,10 +712,18 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans, | |||
711 | btrfs_create_pending_block_groups(trans, root); | 712 | btrfs_create_pending_block_groups(trans, root); |
712 | 713 | ||
713 | trans->delayed_ref_updates = 0; | 714 | trans->delayed_ref_updates = 0; |
714 | if (!trans->sync && btrfs_should_throttle_delayed_refs(trans, root)) { | 715 | if (!trans->sync) { |
716 | must_run_delayed_refs = | ||
717 | btrfs_should_throttle_delayed_refs(trans, root); | ||
715 | cur = max_t(unsigned long, cur, 32); | 718 | cur = max_t(unsigned long, cur, 32); |
716 | trans->delayed_ref_updates = 0; | 719 | |
717 | btrfs_run_delayed_refs(trans, root, cur); | 720 | /* |
721 | * don't make the caller wait if they are from a NOLOCK | ||
722 | * or ATTACH transaction, it will deadlock with commit | ||
723 | */ | ||
724 | if (must_run_delayed_refs == 1 && | ||
725 | (trans->type & (__TRANS_JOIN_NOLOCK | __TRANS_ATTACH))) | ||
726 | must_run_delayed_refs = 2; | ||
718 | } | 727 | } |
719 | 728 | ||
720 | if (trans->qgroup_reserved) { | 729 | if (trans->qgroup_reserved) { |
@@ -775,6 +784,10 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans, | |||
775 | assert_qgroups_uptodate(trans); | 784 | assert_qgroups_uptodate(trans); |
776 | 785 | ||
777 | kmem_cache_free(btrfs_trans_handle_cachep, trans); | 786 | kmem_cache_free(btrfs_trans_handle_cachep, trans); |
787 | if (must_run_delayed_refs) { | ||
788 | btrfs_async_run_delayed_refs(root, cur, | ||
789 | must_run_delayed_refs == 1); | ||
790 | } | ||
778 | return err; | 791 | return err; |
779 | } | 792 | } |
780 | 793 | ||