aboutsummaryrefslogtreecommitdiffstats
path: root/fs
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
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')
-rw-r--r--fs/btrfs/dev-replace.c4
-rw-r--r--fs/btrfs/extent-tree.c11
-rw-r--r--fs/btrfs/ioctl.c2
-rw-r--r--fs/btrfs/ordered-data.c22
-rw-r--r--fs/btrfs/ordered-data.h4
-rw-r--r--fs/btrfs/relocation.c2
-rw-r--r--fs/btrfs/super.c2
-rw-r--r--fs/btrfs/transaction.c2
8 files changed, 31 insertions, 18 deletions
diff --git a/fs/btrfs/dev-replace.c b/fs/btrfs/dev-replace.c
index cb94310db072..3d2495e83e62 100644
--- a/fs/btrfs/dev-replace.c
+++ b/fs/btrfs/dev-replace.c
@@ -391,7 +391,7 @@ int btrfs_dev_replace_start(struct btrfs_root *root,
391 args->result = BTRFS_IOCTL_DEV_REPLACE_RESULT_NO_ERROR; 391 args->result = BTRFS_IOCTL_DEV_REPLACE_RESULT_NO_ERROR;
392 btrfs_dev_replace_unlock(dev_replace); 392 btrfs_dev_replace_unlock(dev_replace);
393 393
394 btrfs_wait_all_ordered_extents(root->fs_info); 394 btrfs_wait_ordered_roots(root->fs_info, -1);
395 395
396 /* force writing the updated state information to disk */ 396 /* force writing the updated state information to disk */
397 trans = btrfs_start_transaction(root, 0); 397 trans = btrfs_start_transaction(root, 0);
@@ -466,7 +466,7 @@ static int btrfs_dev_replace_finishing(struct btrfs_fs_info *fs_info,
466 mutex_unlock(&dev_replace->lock_finishing_cancel_unmount); 466 mutex_unlock(&dev_replace->lock_finishing_cancel_unmount);
467 return ret; 467 return ret;
468 } 468 }
469 btrfs_wait_all_ordered_extents(root->fs_info); 469 btrfs_wait_ordered_roots(root->fs_info, -1);
470 470
471 trans = btrfs_start_transaction(root, 0); 471 trans = btrfs_start_transaction(root, 0);
472 if (IS_ERR(trans)) { 472 if (IS_ERR(trans)) {
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 83bffbea7d97..a21bbf83fdc2 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -4018,7 +4018,7 @@ static void btrfs_writeback_inodes_sb_nr(struct btrfs_root *root,
4018 */ 4018 */
4019 btrfs_start_all_delalloc_inodes(root->fs_info, 0); 4019 btrfs_start_all_delalloc_inodes(root->fs_info, 0);
4020 if (!current->journal_info) 4020 if (!current->journal_info)
4021 btrfs_wait_all_ordered_extents(root->fs_info); 4021 btrfs_wait_ordered_roots(root->fs_info, -1);
4022 } 4022 }
4023} 4023}
4024 4024
@@ -4050,11 +4050,12 @@ static void shrink_delalloc(struct btrfs_root *root, u64 to_reclaim, u64 orig,
4050 long time_left; 4050 long time_left;
4051 unsigned long nr_pages; 4051 unsigned long nr_pages;
4052 int loops; 4052 int loops;
4053 int items;
4053 enum btrfs_reserve_flush_enum flush; 4054 enum btrfs_reserve_flush_enum flush;
4054 4055
4055 /* Calc the number of the pages we need flush for space reservation */ 4056 /* Calc the number of the pages we need flush for space reservation */
4056 to_reclaim = calc_reclaim_items_nr(root, to_reclaim); 4057 items = calc_reclaim_items_nr(root, to_reclaim);
4057 to_reclaim *= EXTENT_SIZE_PER_ITEM; 4058 to_reclaim = items * EXTENT_SIZE_PER_ITEM;
4058 4059
4059 trans = (struct btrfs_trans_handle *)current->journal_info; 4060 trans = (struct btrfs_trans_handle *)current->journal_info;
4060 block_rsv = &root->fs_info->delalloc_block_rsv; 4061 block_rsv = &root->fs_info->delalloc_block_rsv;
@@ -4066,7 +4067,7 @@ static void shrink_delalloc(struct btrfs_root *root, u64 to_reclaim, u64 orig,
4066 if (trans) 4067 if (trans)
4067 return; 4068 return;
4068 if (wait_ordered) 4069 if (wait_ordered)
4069 btrfs_wait_all_ordered_extents(root->fs_info); 4070 btrfs_wait_ordered_roots(root->fs_info, items);
4070 return; 4071 return;
4071 } 4072 }
4072 4073
@@ -4105,7 +4106,7 @@ skip_async:
4105 4106
4106 loops++; 4107 loops++;
4107 if (wait_ordered && !trans) { 4108 if (wait_ordered && !trans) {
4108 btrfs_wait_all_ordered_extents(root->fs_info); 4109 btrfs_wait_ordered_roots(root->fs_info, items);
4109 } else { 4110 } else {
4110 time_left = schedule_timeout_killable(1); 4111 time_left = schedule_timeout_killable(1);
4111 if (time_left) 4112 if (time_left)
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 6523108d2984..d4f2861b0d9e 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -572,7 +572,7 @@ static int create_snapshot(struct btrfs_root *root, struct inode *dir,
572 if (ret) 572 if (ret)
573 return ret; 573 return ret;
574 574
575 btrfs_wait_ordered_extents(root); 575 btrfs_wait_ordered_extents(root, -1);
576 576
577 pending_snapshot = kzalloc(sizeof(*pending_snapshot), GFP_NOFS); 577 pending_snapshot = kzalloc(sizeof(*pending_snapshot), GFP_NOFS);
578 if (!pending_snapshot) 578 if (!pending_snapshot)
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}
diff --git a/fs/btrfs/ordered-data.h b/fs/btrfs/ordered-data.h
index 3982db1c1b36..9b0450f7ac20 100644
--- a/fs/btrfs/ordered-data.h
+++ b/fs/btrfs/ordered-data.h
@@ -195,8 +195,8 @@ int btrfs_run_ordered_operations(struct btrfs_trans_handle *trans,
195void btrfs_add_ordered_operation(struct btrfs_trans_handle *trans, 195void btrfs_add_ordered_operation(struct btrfs_trans_handle *trans,
196 struct btrfs_root *root, 196 struct btrfs_root *root,
197 struct inode *inode); 197 struct inode *inode);
198void btrfs_wait_ordered_extents(struct btrfs_root *root); 198int btrfs_wait_ordered_extents(struct btrfs_root *root, int nr);
199void btrfs_wait_all_ordered_extents(struct btrfs_fs_info *fs_info); 199void btrfs_wait_ordered_roots(struct btrfs_fs_info *fs_info, int nr);
200void btrfs_get_logged_extents(struct btrfs_root *log, struct inode *inode); 200void btrfs_get_logged_extents(struct btrfs_root *log, struct inode *inode);
201void btrfs_wait_logged_extents(struct btrfs_root *log, u64 transid); 201void btrfs_wait_logged_extents(struct btrfs_root *log, u64 transid);
202void btrfs_free_logged_extents(struct btrfs_root *log, u64 transid); 202void btrfs_free_logged_extents(struct btrfs_root *log, u64 transid);
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index 70eca79bae52..e1b3c2c73c44 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -4227,7 +4227,7 @@ int btrfs_relocate_block_group(struct btrfs_root *extent_root, u64 group_start)
4227 err = ret; 4227 err = ret;
4228 goto out; 4228 goto out;
4229 } 4229 }
4230 btrfs_wait_all_ordered_extents(fs_info); 4230 btrfs_wait_ordered_roots(fs_info, -1);
4231 4231
4232 while (1) { 4232 while (1) {
4233 mutex_lock(&fs_info->cleaner_mutex); 4233 mutex_lock(&fs_info->cleaner_mutex);
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 1de6d4d67431..2d8ac1bf0cf9 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -920,7 +920,7 @@ int btrfs_sync_fs(struct super_block *sb, int wait)
920 return 0; 920 return 0;
921 } 921 }
922 922
923 btrfs_wait_all_ordered_extents(fs_info); 923 btrfs_wait_ordered_roots(fs_info, -1);
924 924
925 trans = btrfs_attach_transaction_barrier(root); 925 trans = btrfs_attach_transaction_barrier(root);
926 if (IS_ERR(trans)) { 926 if (IS_ERR(trans)) {
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 277fe812d047..32c100b8c563 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -1636,7 +1636,7 @@ static inline int btrfs_start_delalloc_flush(struct btrfs_fs_info *fs_info)
1636static inline void btrfs_wait_delalloc_flush(struct btrfs_fs_info *fs_info) 1636static inline void btrfs_wait_delalloc_flush(struct btrfs_fs_info *fs_info)
1637{ 1637{
1638 if (btrfs_test_opt(fs_info->tree_root, FLUSHONCOMMIT)) 1638 if (btrfs_test_opt(fs_info->tree_root, FLUSHONCOMMIT))
1639 btrfs_wait_all_ordered_extents(fs_info); 1639 btrfs_wait_ordered_roots(fs_info, -1);
1640} 1640}
1641 1641
1642int btrfs_commit_transaction(struct btrfs_trans_handle *trans, 1642int btrfs_commit_transaction(struct btrfs_trans_handle *trans,