diff options
author | Miao Xie <miaox@cn.fujitsu.com> | 2014-03-06 00:54:55 -0500 |
---|---|---|
committer | Josef Bacik <jbacik@fb.com> | 2014-03-10 15:17:22 -0400 |
commit | 8b9d83cd6bebe10e9965d2cef8053b02663eaad8 (patch) | |
tree | 40603d4f493836043693f81cf658847017998d5f /fs/btrfs/ordered-data.c | |
parent | 8257b2dc3c1a1057b84a589827354abdc4c767fd (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.c | 17 |
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 | */ |
592 | int btrfs_wait_ordered_extents(struct btrfs_root *root, int nr) | 592 | static 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 | |||
636 | int 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 | /* |