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); |
