diff options
Diffstat (limited to 'fs/btrfs/delayed-ref.c')
| -rw-r--r-- | fs/btrfs/delayed-ref.c | 56 | 
1 files changed, 32 insertions, 24 deletions
| diff --git a/fs/btrfs/delayed-ref.c b/fs/btrfs/delayed-ref.c index 13ae7b04790e..da7419ed01bb 100644 --- a/fs/btrfs/delayed-ref.c +++ b/fs/btrfs/delayed-ref.c | |||
| @@ -233,22 +233,26 @@ int btrfs_delayed_ref_lock(struct btrfs_trans_handle *trans, | |||
| 233 | return 0; | 233 | return 0; | 
| 234 | } | 234 | } | 
| 235 | 235 | ||
| 236 | int btrfs_check_delayed_seq(struct btrfs_delayed_ref_root *delayed_refs, | 236 | int btrfs_check_delayed_seq(struct btrfs_fs_info *fs_info, | 
| 237 | struct btrfs_delayed_ref_root *delayed_refs, | ||
| 237 | u64 seq) | 238 | u64 seq) | 
| 238 | { | 239 | { | 
| 239 | struct seq_list *elem; | 240 | struct seq_list *elem; | 
| 240 | 241 | int ret = 0; | |
| 241 | assert_spin_locked(&delayed_refs->lock); | 242 | |
| 242 | if (list_empty(&delayed_refs->seq_head)) | 243 | spin_lock(&fs_info->tree_mod_seq_lock); | 
| 243 | return 0; | 244 | if (!list_empty(&fs_info->tree_mod_seq_list)) { | 
| 244 | 245 | elem = list_first_entry(&fs_info->tree_mod_seq_list, | |
| 245 | elem = list_first_entry(&delayed_refs->seq_head, struct seq_list, list); | 246 | struct seq_list, list); | 
| 246 | if (seq >= elem->seq) { | 247 | if (seq >= elem->seq) { | 
| 247 | pr_debug("holding back delayed_ref %llu, lowest is %llu (%p)\n", | 248 | pr_debug("holding back delayed_ref %llu, lowest is " | 
| 248 | seq, elem->seq, delayed_refs); | 249 | "%llu (%p)\n", seq, elem->seq, delayed_refs); | 
| 249 | return 1; | 250 | ret = 1; | 
| 251 | } | ||
| 250 | } | 252 | } | 
| 251 | return 0; | 253 | |
| 254 | spin_unlock(&fs_info->tree_mod_seq_lock); | ||
| 255 | return ret; | ||
| 252 | } | 256 | } | 
| 253 | 257 | ||
| 254 | int btrfs_find_ref_cluster(struct btrfs_trans_handle *trans, | 258 | int btrfs_find_ref_cluster(struct btrfs_trans_handle *trans, | 
| @@ -525,8 +529,8 @@ static noinline void add_delayed_tree_ref(struct btrfs_fs_info *fs_info, | |||
| 525 | ref->is_head = 0; | 529 | ref->is_head = 0; | 
| 526 | ref->in_tree = 1; | 530 | ref->in_tree = 1; | 
| 527 | 531 | ||
| 528 | if (is_fstree(ref_root)) | 532 | if (need_ref_seq(for_cow, ref_root)) | 
| 529 | seq = inc_delayed_seq(delayed_refs); | 533 | seq = btrfs_get_tree_mod_seq(fs_info, &trans->delayed_ref_elem); | 
| 530 | ref->seq = seq; | 534 | ref->seq = seq; | 
| 531 | 535 | ||
| 532 | full_ref = btrfs_delayed_node_to_tree_ref(ref); | 536 | full_ref = btrfs_delayed_node_to_tree_ref(ref); | 
| @@ -584,8 +588,8 @@ static noinline void add_delayed_data_ref(struct btrfs_fs_info *fs_info, | |||
| 584 | ref->is_head = 0; | 588 | ref->is_head = 0; | 
| 585 | ref->in_tree = 1; | 589 | ref->in_tree = 1; | 
| 586 | 590 | ||
| 587 | if (is_fstree(ref_root)) | 591 | if (need_ref_seq(for_cow, ref_root)) | 
| 588 | seq = inc_delayed_seq(delayed_refs); | 592 | seq = btrfs_get_tree_mod_seq(fs_info, &trans->delayed_ref_elem); | 
| 589 | ref->seq = seq; | 593 | ref->seq = seq; | 
| 590 | 594 | ||
| 591 | full_ref = btrfs_delayed_node_to_data_ref(ref); | 595 | full_ref = btrfs_delayed_node_to_data_ref(ref); | 
| @@ -658,10 +662,12 @@ int btrfs_add_delayed_tree_ref(struct btrfs_fs_info *fs_info, | |||
| 658 | add_delayed_tree_ref(fs_info, trans, &ref->node, bytenr, | 662 | add_delayed_tree_ref(fs_info, trans, &ref->node, bytenr, | 
| 659 | num_bytes, parent, ref_root, level, action, | 663 | num_bytes, parent, ref_root, level, action, | 
| 660 | for_cow); | 664 | for_cow); | 
| 661 | if (!is_fstree(ref_root) && | 665 | if (!need_ref_seq(for_cow, ref_root) && | 
| 662 | waitqueue_active(&delayed_refs->seq_wait)) | 666 | waitqueue_active(&fs_info->tree_mod_seq_wait)) | 
| 663 | wake_up(&delayed_refs->seq_wait); | 667 | wake_up(&fs_info->tree_mod_seq_wait); | 
| 664 | spin_unlock(&delayed_refs->lock); | 668 | spin_unlock(&delayed_refs->lock); | 
| 669 | if (need_ref_seq(for_cow, ref_root)) | ||
| 670 | btrfs_qgroup_record_ref(trans, &ref->node, extent_op); | ||
| 665 | 671 | ||
| 666 | return 0; | 672 | return 0; | 
| 667 | } | 673 | } | 
| @@ -707,10 +713,12 @@ int btrfs_add_delayed_data_ref(struct btrfs_fs_info *fs_info, | |||
| 707 | add_delayed_data_ref(fs_info, trans, &ref->node, bytenr, | 713 | add_delayed_data_ref(fs_info, trans, &ref->node, bytenr, | 
| 708 | num_bytes, parent, ref_root, owner, offset, | 714 | num_bytes, parent, ref_root, owner, offset, | 
| 709 | action, for_cow); | 715 | action, for_cow); | 
| 710 | if (!is_fstree(ref_root) && | 716 | if (!need_ref_seq(for_cow, ref_root) && | 
| 711 | waitqueue_active(&delayed_refs->seq_wait)) | 717 | waitqueue_active(&fs_info->tree_mod_seq_wait)) | 
| 712 | wake_up(&delayed_refs->seq_wait); | 718 | wake_up(&fs_info->tree_mod_seq_wait); | 
| 713 | spin_unlock(&delayed_refs->lock); | 719 | spin_unlock(&delayed_refs->lock); | 
| 720 | if (need_ref_seq(for_cow, ref_root)) | ||
| 721 | btrfs_qgroup_record_ref(trans, &ref->node, extent_op); | ||
| 714 | 722 | ||
| 715 | return 0; | 723 | return 0; | 
| 716 | } | 724 | } | 
| @@ -736,8 +744,8 @@ int btrfs_add_delayed_extent_op(struct btrfs_fs_info *fs_info, | |||
| 736 | num_bytes, BTRFS_UPDATE_DELAYED_HEAD, | 744 | num_bytes, BTRFS_UPDATE_DELAYED_HEAD, | 
| 737 | extent_op->is_data); | 745 | extent_op->is_data); | 
| 738 | 746 | ||
| 739 | if (waitqueue_active(&delayed_refs->seq_wait)) | 747 | if (waitqueue_active(&fs_info->tree_mod_seq_wait)) | 
| 740 | wake_up(&delayed_refs->seq_wait); | 748 | wake_up(&fs_info->tree_mod_seq_wait); | 
| 741 | spin_unlock(&delayed_refs->lock); | 749 | spin_unlock(&delayed_refs->lock); | 
| 742 | return 0; | 750 | return 0; | 
| 743 | } | 751 | } | 
