diff options
Diffstat (limited to 'fs/btrfs/ordered-data.c')
-rw-r--r-- | fs/btrfs/ordered-data.c | 26 |
1 files changed, 19 insertions, 7 deletions
diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c index 0de7da5a610d..559170464d7c 100644 --- a/fs/btrfs/ordered-data.c +++ b/fs/btrfs/ordered-data.c | |||
@@ -661,14 +661,15 @@ static void btrfs_run_ordered_extent_work(struct btrfs_work *work) | |||
661 | * wait for all the ordered extents in a root. This is done when balancing | 661 | * wait for all the ordered extents in a root. This is done when balancing |
662 | * space between drives. | 662 | * space between drives. |
663 | */ | 663 | */ |
664 | int btrfs_wait_ordered_extents(struct btrfs_root *root, int nr) | 664 | int btrfs_wait_ordered_extents(struct btrfs_root *root, int nr, |
665 | const u64 range_start, const u64 range_len) | ||
665 | { | 666 | { |
666 | struct list_head splice, works; | 667 | LIST_HEAD(splice); |
668 | LIST_HEAD(skipped); | ||
669 | LIST_HEAD(works); | ||
667 | struct btrfs_ordered_extent *ordered, *next; | 670 | struct btrfs_ordered_extent *ordered, *next; |
668 | int count = 0; | 671 | int count = 0; |
669 | 672 | const u64 range_end = range_start + range_len; | |
670 | INIT_LIST_HEAD(&splice); | ||
671 | INIT_LIST_HEAD(&works); | ||
672 | 673 | ||
673 | mutex_lock(&root->ordered_extent_mutex); | 674 | mutex_lock(&root->ordered_extent_mutex); |
674 | spin_lock(&root->ordered_extent_lock); | 675 | spin_lock(&root->ordered_extent_lock); |
@@ -676,6 +677,14 @@ int btrfs_wait_ordered_extents(struct btrfs_root *root, int nr) | |||
676 | while (!list_empty(&splice) && nr) { | 677 | while (!list_empty(&splice) && nr) { |
677 | ordered = list_first_entry(&splice, struct btrfs_ordered_extent, | 678 | ordered = list_first_entry(&splice, struct btrfs_ordered_extent, |
678 | root_extent_list); | 679 | root_extent_list); |
680 | |||
681 | if (range_end <= ordered->start || | ||
682 | ordered->start + ordered->disk_len <= range_start) { | ||
683 | list_move_tail(&ordered->root_extent_list, &skipped); | ||
684 | cond_resched_lock(&root->ordered_extent_lock); | ||
685 | continue; | ||
686 | } | ||
687 | |||
679 | list_move_tail(&ordered->root_extent_list, | 688 | list_move_tail(&ordered->root_extent_list, |
680 | &root->ordered_extents); | 689 | &root->ordered_extents); |
681 | atomic_inc(&ordered->refs); | 690 | atomic_inc(&ordered->refs); |
@@ -694,6 +703,7 @@ int btrfs_wait_ordered_extents(struct btrfs_root *root, int nr) | |||
694 | nr--; | 703 | nr--; |
695 | count++; | 704 | count++; |
696 | } | 705 | } |
706 | list_splice_tail(&skipped, &root->ordered_extents); | ||
697 | list_splice_tail(&splice, &root->ordered_extents); | 707 | list_splice_tail(&splice, &root->ordered_extents); |
698 | spin_unlock(&root->ordered_extent_lock); | 708 | spin_unlock(&root->ordered_extent_lock); |
699 | 709 | ||
@@ -708,7 +718,8 @@ int btrfs_wait_ordered_extents(struct btrfs_root *root, int nr) | |||
708 | return count; | 718 | return count; |
709 | } | 719 | } |
710 | 720 | ||
711 | void btrfs_wait_ordered_roots(struct btrfs_fs_info *fs_info, int nr) | 721 | void btrfs_wait_ordered_roots(struct btrfs_fs_info *fs_info, int nr, |
722 | const u64 range_start, const u64 range_len) | ||
712 | { | 723 | { |
713 | struct btrfs_root *root; | 724 | struct btrfs_root *root; |
714 | struct list_head splice; | 725 | struct list_head splice; |
@@ -728,7 +739,8 @@ void btrfs_wait_ordered_roots(struct btrfs_fs_info *fs_info, int nr) | |||
728 | &fs_info->ordered_roots); | 739 | &fs_info->ordered_roots); |
729 | spin_unlock(&fs_info->ordered_root_lock); | 740 | spin_unlock(&fs_info->ordered_root_lock); |
730 | 741 | ||
731 | done = btrfs_wait_ordered_extents(root, nr); | 742 | done = btrfs_wait_ordered_extents(root, nr, |
743 | range_start, range_len); | ||
732 | btrfs_put_fs_root(root); | 744 | btrfs_put_fs_root(root); |
733 | 745 | ||
734 | spin_lock(&fs_info->ordered_root_lock); | 746 | spin_lock(&fs_info->ordered_root_lock); |