aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/ordered-data.c
diff options
context:
space:
mode:
authorMiao Xie <miaox@cn.fujitsu.com>2013-11-04 10:13:25 -0500
committerChris Mason <chris.mason@fusionio.com>2013-11-11 22:13:44 -0500
commitb02441999efcc6152b87cd58e7970bb7843f76cf (patch)
tree36f8e823f3ee84528f3f030323b472a72a915094 /fs/btrfs/ordered-data.c
parent9f3a074d108810139ad4af49a29d347a4cf41e9a (diff)
Btrfs: don't wait for the completion of all the ordered extents
It is very likely that there are lots of ordered extents in the filesytem, if we wait for the completion of all of them when we want to reclaim some space for the metadata space reservation, we would be blocked for a long time. The performance would drop down suddenly for a long time. Signed-off-by: Miao Xie <miaox@cn.fujitsu.com> Signed-off-by: Josef Bacik <jbacik@fusionio.com> Signed-off-by: Chris Mason <chris.mason@fusionio.com>
Diffstat (limited to 'fs/btrfs/ordered-data.c')
-rw-r--r--fs/btrfs/ordered-data.c22
1 files changed, 17 insertions, 5 deletions
diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c
index 8a5eff366596..25a8f3812f14 100644
--- a/fs/btrfs/ordered-data.c
+++ b/fs/btrfs/ordered-data.c
@@ -565,10 +565,11 @@ static void btrfs_run_ordered_extent_work(struct btrfs_work *work)
565 * wait for all the ordered extents in a root. This is done when balancing 565 * wait for all the ordered extents in a root. This is done when balancing
566 * space between drives. 566 * space between drives.
567 */ 567 */
568void btrfs_wait_ordered_extents(struct btrfs_root *root) 568int btrfs_wait_ordered_extents(struct btrfs_root *root, int nr)
569{ 569{
570 struct list_head splice, works; 570 struct list_head splice, works;
571 struct btrfs_ordered_extent *ordered, *next; 571 struct btrfs_ordered_extent *ordered, *next;
572 int count = 0;
572 573
573 INIT_LIST_HEAD(&splice); 574 INIT_LIST_HEAD(&splice);
574 INIT_LIST_HEAD(&works); 575 INIT_LIST_HEAD(&works);
@@ -576,7 +577,7 @@ void btrfs_wait_ordered_extents(struct btrfs_root *root)
576 mutex_lock(&root->fs_info->ordered_operations_mutex); 577 mutex_lock(&root->fs_info->ordered_operations_mutex);
577 spin_lock(&root->ordered_extent_lock); 578 spin_lock(&root->ordered_extent_lock);
578 list_splice_init(&root->ordered_extents, &splice); 579 list_splice_init(&root->ordered_extents, &splice);
579 while (!list_empty(&splice)) { 580 while (!list_empty(&splice) && nr) {
580 ordered = list_first_entry(&splice, struct btrfs_ordered_extent, 581 ordered = list_first_entry(&splice, struct btrfs_ordered_extent,
581 root_extent_list); 582 root_extent_list);
582 list_move_tail(&ordered->root_extent_list, 583 list_move_tail(&ordered->root_extent_list,
@@ -591,7 +592,11 @@ void btrfs_wait_ordered_extents(struct btrfs_root *root)
591 592
592 cond_resched(); 593 cond_resched();
593 spin_lock(&root->ordered_extent_lock); 594 spin_lock(&root->ordered_extent_lock);
595 if (nr != -1)
596 nr--;
597 count++;
594 } 598 }
599 list_splice_tail(&splice, &root->ordered_extents);
595 spin_unlock(&root->ordered_extent_lock); 600 spin_unlock(&root->ordered_extent_lock);
596 601
597 list_for_each_entry_safe(ordered, next, &works, work_list) { 602 list_for_each_entry_safe(ordered, next, &works, work_list) {
@@ -601,18 +606,21 @@ void btrfs_wait_ordered_extents(struct btrfs_root *root)
601 cond_resched(); 606 cond_resched();
602 } 607 }
603 mutex_unlock(&root->fs_info->ordered_operations_mutex); 608 mutex_unlock(&root->fs_info->ordered_operations_mutex);
609
610 return count;
604} 611}
605 612
606void btrfs_wait_all_ordered_extents(struct btrfs_fs_info *fs_info) 613void btrfs_wait_ordered_roots(struct btrfs_fs_info *fs_info, int nr)
607{ 614{
608 struct btrfs_root *root; 615 struct btrfs_root *root;
609 struct list_head splice; 616 struct list_head splice;
617 int done;
610 618
611 INIT_LIST_HEAD(&splice); 619 INIT_LIST_HEAD(&splice);
612 620
613 spin_lock(&fs_info->ordered_root_lock); 621 spin_lock(&fs_info->ordered_root_lock);
614 list_splice_init(&fs_info->ordered_roots, &splice); 622 list_splice_init(&fs_info->ordered_roots, &splice);
615 while (!list_empty(&splice)) { 623 while (!list_empty(&splice) && nr) {
616 root = list_first_entry(&splice, struct btrfs_root, 624 root = list_first_entry(&splice, struct btrfs_root,
617 ordered_root); 625 ordered_root);
618 root = btrfs_grab_fs_root(root); 626 root = btrfs_grab_fs_root(root);
@@ -621,10 +629,14 @@ void btrfs_wait_all_ordered_extents(struct btrfs_fs_info *fs_info)
621 &fs_info->ordered_roots); 629 &fs_info->ordered_roots);
622 spin_unlock(&fs_info->ordered_root_lock); 630 spin_unlock(&fs_info->ordered_root_lock);
623 631
624 btrfs_wait_ordered_extents(root); 632 done = btrfs_wait_ordered_extents(root, nr);
625 btrfs_put_fs_root(root); 633 btrfs_put_fs_root(root);
626 634
627 spin_lock(&fs_info->ordered_root_lock); 635 spin_lock(&fs_info->ordered_root_lock);
636 if (nr != -1) {
637 nr -= done;
638 WARN_ON(nr < 0);
639 }
628 } 640 }
629 spin_unlock(&fs_info->ordered_root_lock); 641 spin_unlock(&fs_info->ordered_root_lock);
630} 642}