aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/ordered-data.c
diff options
context:
space:
mode:
authorMiao Xie <miaox@cn.fujitsu.com>2014-03-06 00:54:55 -0500
committerJosef Bacik <jbacik@fb.com>2014-03-10 15:17:22 -0400
commit8b9d83cd6bebe10e9965d2cef8053b02663eaad8 (patch)
tree40603d4f493836043693f81cf658847017998d5f /fs/btrfs/ordered-data.c
parent8257b2dc3c1a1057b84a589827354abdc4c767fd (diff)
Btrfs: fix early enospc due to the race of the two ordered extent wait
btrfs_wait_ordered_roots() moves all the list entries to a new list, and then deals with them one by one. But if the other task invokes this function at that time, it would get a empty list. It makes the enospc error happens more early. Fix it. Signed-off-by: Miao Xie <miaox@cn.fujitsu.com> Signed-off-by: Josef Bacik <jbacik@fb.com>
Diffstat (limited to 'fs/btrfs/ordered-data.c')
-rw-r--r--fs/btrfs/ordered-data.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c
index 751ee38083a9..73de19c37f5a 100644
--- a/fs/btrfs/ordered-data.c
+++ b/fs/btrfs/ordered-data.c
@@ -589,7 +589,7 @@ static void btrfs_run_ordered_extent_work(struct btrfs_work *work)
589 * wait for all the ordered extents in a root. This is done when balancing 589 * wait for all the ordered extents in a root. This is done when balancing
590 * space between drives. 590 * space between drives.
591 */ 591 */
592int btrfs_wait_ordered_extents(struct btrfs_root *root, int nr) 592static int __btrfs_wait_ordered_extents(struct btrfs_root *root, int nr)
593{ 593{
594 struct list_head splice, works; 594 struct list_head splice, works;
595 struct btrfs_ordered_extent *ordered, *next; 595 struct btrfs_ordered_extent *ordered, *next;
@@ -598,7 +598,6 @@ int btrfs_wait_ordered_extents(struct btrfs_root *root, int nr)
598 INIT_LIST_HEAD(&splice); 598 INIT_LIST_HEAD(&splice);
599 INIT_LIST_HEAD(&works); 599 INIT_LIST_HEAD(&works);
600 600
601 mutex_lock(&root->fs_info->ordered_operations_mutex);
602 spin_lock(&root->ordered_extent_lock); 601 spin_lock(&root->ordered_extent_lock);
603 list_splice_init(&root->ordered_extents, &splice); 602 list_splice_init(&root->ordered_extents, &splice);
604 while (!list_empty(&splice) && nr) { 603 while (!list_empty(&splice) && nr) {
@@ -630,6 +629,16 @@ int btrfs_wait_ordered_extents(struct btrfs_root *root, int nr)
630 btrfs_put_ordered_extent(ordered); 629 btrfs_put_ordered_extent(ordered);
631 cond_resched(); 630 cond_resched();
632 } 631 }
632
633 return count;
634}
635
636int btrfs_wait_ordered_extents(struct btrfs_root *root, int nr)
637{
638 int count;
639
640 mutex_lock(&root->fs_info->ordered_operations_mutex);
641 count = __btrfs_wait_ordered_extents(root, nr);
633 mutex_unlock(&root->fs_info->ordered_operations_mutex); 642 mutex_unlock(&root->fs_info->ordered_operations_mutex);
634 643
635 return count; 644 return count;
@@ -643,6 +652,7 @@ void btrfs_wait_ordered_roots(struct btrfs_fs_info *fs_info, int nr)
643 652
644 INIT_LIST_HEAD(&splice); 653 INIT_LIST_HEAD(&splice);
645 654
655 mutex_lock(&fs_info->ordered_operations_mutex);
646 spin_lock(&fs_info->ordered_root_lock); 656 spin_lock(&fs_info->ordered_root_lock);
647 list_splice_init(&fs_info->ordered_roots, &splice); 657 list_splice_init(&fs_info->ordered_roots, &splice);
648 while (!list_empty(&splice) && nr) { 658 while (!list_empty(&splice) && nr) {
@@ -654,7 +664,7 @@ void btrfs_wait_ordered_roots(struct btrfs_fs_info *fs_info, int nr)
654 &fs_info->ordered_roots); 664 &fs_info->ordered_roots);
655 spin_unlock(&fs_info->ordered_root_lock); 665 spin_unlock(&fs_info->ordered_root_lock);
656 666
657 done = btrfs_wait_ordered_extents(root, nr); 667 done = __btrfs_wait_ordered_extents(root, nr);
658 btrfs_put_fs_root(root); 668 btrfs_put_fs_root(root);
659 669
660 spin_lock(&fs_info->ordered_root_lock); 670 spin_lock(&fs_info->ordered_root_lock);
@@ -665,6 +675,7 @@ void btrfs_wait_ordered_roots(struct btrfs_fs_info *fs_info, int nr)
665 } 675 }
666 list_splice_tail(&splice, &fs_info->ordered_roots); 676 list_splice_tail(&splice, &fs_info->ordered_roots);
667 spin_unlock(&fs_info->ordered_root_lock); 677 spin_unlock(&fs_info->ordered_root_lock);
678 mutex_unlock(&fs_info->ordered_operations_mutex);
668} 679}
669 680
670/* 681/*