aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
authorMiao Xie <miaox@cn.fujitsu.com>2014-03-06 00:55:01 -0500
committerJosef Bacik <jbacik@fb.com>2014-03-10 15:17:27 -0400
commit6c255e67cec1c38a0569c7f823eba63f9449ccf8 (patch)
tree0e23bdebb81ce14843d85dd0deb861cc2c0ef5fb /fs/btrfs
parent24af7dd1881f9f5c13c7d82e22d7858137383766 (diff)
Btrfs: don't flush all delalloc inodes when we doesn't get s_umount lock
We needn't flush all delalloc inodes when we doesn't get s_umount lock, or we would make the tasks wait for a long time. Signed-off-by: Miao Xie <miaox@cn.fujitsu.com> Signed-off-by: Josef Bacik <jbacik@fb.com>
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/ctree.h3
-rw-r--r--fs/btrfs/dev-replace.c2
-rw-r--r--fs/btrfs/extent-tree.c8
-rw-r--r--fs/btrfs/inode.c34
-rw-r--r--fs/btrfs/ioctl.c2
-rw-r--r--fs/btrfs/relocation.c2
-rw-r--r--fs/btrfs/transaction.c2
7 files changed, 29 insertions, 24 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 374bb2f8ccd9..5a800986f416 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -3740,7 +3740,8 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans,
3740 u32 min_type); 3740 u32 min_type);
3741 3741
3742int btrfs_start_delalloc_inodes(struct btrfs_root *root, int delay_iput); 3742int btrfs_start_delalloc_inodes(struct btrfs_root *root, int delay_iput);
3743int btrfs_start_delalloc_roots(struct btrfs_fs_info *fs_info, int delay_iput); 3743int btrfs_start_delalloc_roots(struct btrfs_fs_info *fs_info, int delay_iput,
3744 int nr);
3744int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end, 3745int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end,
3745 struct extent_state **cached_state); 3746 struct extent_state **cached_state);
3746int btrfs_create_subvol_root(struct btrfs_trans_handle *trans, 3747int btrfs_create_subvol_root(struct btrfs_trans_handle *trans,
diff --git a/fs/btrfs/dev-replace.c b/fs/btrfs/dev-replace.c
index ec1c3f3a775d..9f2290509aca 100644
--- a/fs/btrfs/dev-replace.c
+++ b/fs/btrfs/dev-replace.c
@@ -491,7 +491,7 @@ static int btrfs_dev_replace_finishing(struct btrfs_fs_info *fs_info,
491 * flush all outstanding I/O and inode extent mappings before the 491 * flush all outstanding I/O and inode extent mappings before the
492 * copy operation is declared as being finished 492 * copy operation is declared as being finished
493 */ 493 */
494 ret = btrfs_start_delalloc_roots(root->fs_info, 0); 494 ret = btrfs_start_delalloc_roots(root->fs_info, 0, -1);
495 if (ret) { 495 if (ret) {
496 mutex_unlock(&dev_replace->lock_finishing_cancel_unmount); 496 mutex_unlock(&dev_replace->lock_finishing_cancel_unmount);
497 return ret; 497 return ret;
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 5c0c5457268a..c6b6a6e3e735 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -3971,7 +3971,7 @@ static int can_overcommit(struct btrfs_root *root,
3971} 3971}
3972 3972
3973static void btrfs_writeback_inodes_sb_nr(struct btrfs_root *root, 3973static void btrfs_writeback_inodes_sb_nr(struct btrfs_root *root,
3974 unsigned long nr_pages) 3974 unsigned long nr_pages, int nr_items)
3975{ 3975{
3976 struct super_block *sb = root->fs_info->sb; 3976 struct super_block *sb = root->fs_info->sb;
3977 3977
@@ -3986,9 +3986,9 @@ static void btrfs_writeback_inodes_sb_nr(struct btrfs_root *root,
3986 * the filesystem is readonly(all dirty pages are written to 3986 * the filesystem is readonly(all dirty pages are written to
3987 * the disk). 3987 * the disk).
3988 */ 3988 */
3989 btrfs_start_delalloc_roots(root->fs_info, 0); 3989 btrfs_start_delalloc_roots(root->fs_info, 0, nr_items);
3990 if (!current->journal_info) 3990 if (!current->journal_info)
3991 btrfs_wait_ordered_roots(root->fs_info, -1); 3991 btrfs_wait_ordered_roots(root->fs_info, nr_items);
3992 } 3992 }
3993} 3993}
3994 3994
@@ -4045,7 +4045,7 @@ static void shrink_delalloc(struct btrfs_root *root, u64 to_reclaim, u64 orig,
4045 while (delalloc_bytes && loops < 3) { 4045 while (delalloc_bytes && loops < 3) {
4046 max_reclaim = min(delalloc_bytes, to_reclaim); 4046 max_reclaim = min(delalloc_bytes, to_reclaim);
4047 nr_pages = max_reclaim >> PAGE_CACHE_SHIFT; 4047 nr_pages = max_reclaim >> PAGE_CACHE_SHIFT;
4048 btrfs_writeback_inodes_sb_nr(root, nr_pages); 4048 btrfs_writeback_inodes_sb_nr(root, nr_pages, items);
4049 /* 4049 /*
4050 * We need to wait for the async pages to actually start before 4050 * We need to wait for the async pages to actually start before
4051 * we do anything. 4051 * we do anything.
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index f5e623371bf3..fbaf1ac3941b 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -8437,7 +8437,8 @@ void btrfs_wait_and_free_delalloc_work(struct btrfs_delalloc_work *work)
8437 * some fairly slow code that needs optimization. This walks the list 8437 * some fairly slow code that needs optimization. This walks the list
8438 * of all the inodes with pending delalloc and forces them to disk. 8438 * of all the inodes with pending delalloc and forces them to disk.
8439 */ 8439 */
8440static int __start_delalloc_inodes(struct btrfs_root *root, int delay_iput) 8440static int __start_delalloc_inodes(struct btrfs_root *root, int delay_iput,
8441 int nr)
8441{ 8442{
8442 struct btrfs_inode *binode; 8443 struct btrfs_inode *binode;
8443 struct inode *inode; 8444 struct inode *inode;
@@ -8471,12 +8472,14 @@ static int __start_delalloc_inodes(struct btrfs_root *root, int delay_iput)
8471 else 8472 else
8472 iput(inode); 8473 iput(inode);
8473 ret = -ENOMEM; 8474 ret = -ENOMEM;
8474 goto out; 8475 break;
8475 } 8476 }
8476 list_add_tail(&work->list, &works); 8477 list_add_tail(&work->list, &works);
8477 btrfs_queue_work(root->fs_info->flush_workers, 8478 btrfs_queue_work(root->fs_info->flush_workers,
8478 &work->work); 8479 &work->work);
8479 8480 ret++;
8481 if (nr != -1 && ret >= nr)
8482 break;
8480 cond_resched(); 8483 cond_resched();
8481 spin_lock(&root->delalloc_lock); 8484 spin_lock(&root->delalloc_lock);
8482 } 8485 }
@@ -8486,12 +8489,6 @@ static int __start_delalloc_inodes(struct btrfs_root *root, int delay_iput)
8486 list_del_init(&work->list); 8489 list_del_init(&work->list);
8487 btrfs_wait_and_free_delalloc_work(work); 8490 btrfs_wait_and_free_delalloc_work(work);
8488 } 8491 }
8489 return 0;
8490out:
8491 list_for_each_entry_safe(work, next, &works, list) {
8492 list_del_init(&work->list);
8493 btrfs_wait_and_free_delalloc_work(work);
8494 }
8495 8492
8496 if (!list_empty_careful(&splice)) { 8493 if (!list_empty_careful(&splice)) {
8497 spin_lock(&root->delalloc_lock); 8494 spin_lock(&root->delalloc_lock);
@@ -8508,7 +8505,9 @@ int btrfs_start_delalloc_inodes(struct btrfs_root *root, int delay_iput)
8508 if (test_bit(BTRFS_FS_STATE_ERROR, &root->fs_info->fs_state)) 8505 if (test_bit(BTRFS_FS_STATE_ERROR, &root->fs_info->fs_state))
8509 return -EROFS; 8506 return -EROFS;
8510 8507
8511 ret = __start_delalloc_inodes(root, delay_iput); 8508 ret = __start_delalloc_inodes(root, delay_iput, -1);
8509 if (ret > 0)
8510 ret = 0;
8512 /* 8511 /*
8513 * the filemap_flush will queue IO into the worker threads, but 8512 * the filemap_flush will queue IO into the worker threads, but
8514 * we have to make sure the IO is actually started and that 8513 * we have to make sure the IO is actually started and that
@@ -8525,7 +8524,8 @@ int btrfs_start_delalloc_inodes(struct btrfs_root *root, int delay_iput)
8525 return ret; 8524 return ret;
8526} 8525}
8527 8526
8528int btrfs_start_delalloc_roots(struct btrfs_fs_info *fs_info, int delay_iput) 8527int btrfs_start_delalloc_roots(struct btrfs_fs_info *fs_info, int delay_iput,
8528 int nr)
8529{ 8529{
8530 struct btrfs_root *root; 8530 struct btrfs_root *root;
8531 struct list_head splice; 8531 struct list_head splice;
@@ -8538,7 +8538,7 @@ int btrfs_start_delalloc_roots(struct btrfs_fs_info *fs_info, int delay_iput)
8538 8538
8539 spin_lock(&fs_info->delalloc_root_lock); 8539 spin_lock(&fs_info->delalloc_root_lock);
8540 list_splice_init(&fs_info->delalloc_roots, &splice); 8540 list_splice_init(&fs_info->delalloc_roots, &splice);
8541 while (!list_empty(&splice)) { 8541 while (!list_empty(&splice) && nr) {
8542 root = list_first_entry(&splice, struct btrfs_root, 8542 root = list_first_entry(&splice, struct btrfs_root,
8543 delalloc_root); 8543 delalloc_root);
8544 root = btrfs_grab_fs_root(root); 8544 root = btrfs_grab_fs_root(root);
@@ -8547,15 +8547,20 @@ int btrfs_start_delalloc_roots(struct btrfs_fs_info *fs_info, int delay_iput)
8547 &fs_info->delalloc_roots); 8547 &fs_info->delalloc_roots);
8548 spin_unlock(&fs_info->delalloc_root_lock); 8548 spin_unlock(&fs_info->delalloc_root_lock);
8549 8549
8550 ret = __start_delalloc_inodes(root, delay_iput); 8550 ret = __start_delalloc_inodes(root, delay_iput, nr);
8551 btrfs_put_fs_root(root); 8551 btrfs_put_fs_root(root);
8552 if (ret) 8552 if (ret < 0)
8553 goto out; 8553 goto out;
8554 8554
8555 if (nr != -1) {
8556 nr -= ret;
8557 WARN_ON(nr < 0);
8558 }
8555 spin_lock(&fs_info->delalloc_root_lock); 8559 spin_lock(&fs_info->delalloc_root_lock);
8556 } 8560 }
8557 spin_unlock(&fs_info->delalloc_root_lock); 8561 spin_unlock(&fs_info->delalloc_root_lock);
8558 8562
8563 ret = 0;
8559 atomic_inc(&fs_info->async_submit_draining); 8564 atomic_inc(&fs_info->async_submit_draining);
8560 while (atomic_read(&fs_info->nr_async_submits) || 8565 while (atomic_read(&fs_info->nr_async_submits) ||
8561 atomic_read(&fs_info->async_delalloc_pages)) { 8566 atomic_read(&fs_info->async_delalloc_pages)) {
@@ -8564,7 +8569,6 @@ int btrfs_start_delalloc_roots(struct btrfs_fs_info *fs_info, int delay_iput)
8564 atomic_read(&fs_info->async_delalloc_pages) == 0)); 8569 atomic_read(&fs_info->async_delalloc_pages) == 0));
8565 } 8570 }
8566 atomic_dec(&fs_info->async_submit_draining); 8571 atomic_dec(&fs_info->async_submit_draining);
8567 return 0;
8568out: 8572out:
8569 if (!list_empty_careful(&splice)) { 8573 if (!list_empty_careful(&splice)) {
8570 spin_lock(&fs_info->delalloc_root_lock); 8574 spin_lock(&fs_info->delalloc_root_lock);
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 57bc9f33fa3c..e1747701f520 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -4893,7 +4893,7 @@ long btrfs_ioctl(struct file *file, unsigned int
4893 case BTRFS_IOC_SYNC: { 4893 case BTRFS_IOC_SYNC: {
4894 int ret; 4894 int ret;
4895 4895
4896 ret = btrfs_start_delalloc_roots(root->fs_info, 0); 4896 ret = btrfs_start_delalloc_roots(root->fs_info, 0, -1);
4897 if (ret) 4897 if (ret)
4898 return ret; 4898 return ret;
4899 ret = btrfs_sync_fs(file->f_dentry->d_sb, 1); 4899 ret = btrfs_sync_fs(file->f_dentry->d_sb, 1);
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index 07b3b36f40ee..def428a25b2a 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -4248,7 +4248,7 @@ int btrfs_relocate_block_group(struct btrfs_root *extent_root, u64 group_start)
4248 btrfs_info(extent_root->fs_info, "relocating block group %llu flags %llu", 4248 btrfs_info(extent_root->fs_info, "relocating block group %llu flags %llu",
4249 rc->block_group->key.objectid, rc->block_group->flags); 4249 rc->block_group->key.objectid, rc->block_group->flags);
4250 4250
4251 ret = btrfs_start_delalloc_roots(fs_info, 0); 4251 ret = btrfs_start_delalloc_roots(fs_info, 0, -1);
4252 if (ret < 0) { 4252 if (ret < 0) {
4253 err = ret; 4253 err = ret;
4254 goto out; 4254 goto out;
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 79a4186b724a..a999b85d1176 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -1620,7 +1620,7 @@ static int btrfs_flush_all_pending_stuffs(struct btrfs_trans_handle *trans,
1620static inline int btrfs_start_delalloc_flush(struct btrfs_fs_info *fs_info) 1620static inline int btrfs_start_delalloc_flush(struct btrfs_fs_info *fs_info)
1621{ 1621{
1622 if (btrfs_test_opt(fs_info->tree_root, FLUSHONCOMMIT)) 1622 if (btrfs_test_opt(fs_info->tree_root, FLUSHONCOMMIT))
1623 return btrfs_start_delalloc_roots(fs_info, 1); 1623 return btrfs_start_delalloc_roots(fs_info, 1, -1);
1624 return 0; 1624 return 0;
1625} 1625}
1626 1626