diff options
author | Miao Xie <miaox@cn.fujitsu.com> | 2014-03-06 00:55:01 -0500 |
---|---|---|
committer | Josef Bacik <jbacik@fb.com> | 2014-03-10 15:17:27 -0400 |
commit | 6c255e67cec1c38a0569c7f823eba63f9449ccf8 (patch) | |
tree | 0e23bdebb81ce14843d85dd0deb861cc2c0ef5fb /fs/btrfs | |
parent | 24af7dd1881f9f5c13c7d82e22d7858137383766 (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.h | 3 | ||||
-rw-r--r-- | fs/btrfs/dev-replace.c | 2 | ||||
-rw-r--r-- | fs/btrfs/extent-tree.c | 8 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 34 | ||||
-rw-r--r-- | fs/btrfs/ioctl.c | 2 | ||||
-rw-r--r-- | fs/btrfs/relocation.c | 2 | ||||
-rw-r--r-- | fs/btrfs/transaction.c | 2 |
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 | ||
3742 | int btrfs_start_delalloc_inodes(struct btrfs_root *root, int delay_iput); | 3742 | int btrfs_start_delalloc_inodes(struct btrfs_root *root, int delay_iput); |
3743 | int btrfs_start_delalloc_roots(struct btrfs_fs_info *fs_info, int delay_iput); | 3743 | int btrfs_start_delalloc_roots(struct btrfs_fs_info *fs_info, int delay_iput, |
3744 | int nr); | ||
3744 | int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end, | 3745 | int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end, |
3745 | struct extent_state **cached_state); | 3746 | struct extent_state **cached_state); |
3746 | int btrfs_create_subvol_root(struct btrfs_trans_handle *trans, | 3747 | int 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 | ||
3973 | static void btrfs_writeback_inodes_sb_nr(struct btrfs_root *root, | 3973 | static 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 | */ |
8440 | static int __start_delalloc_inodes(struct btrfs_root *root, int delay_iput) | 8440 | static 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; | ||
8490 | out: | ||
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 | ||
8528 | int btrfs_start_delalloc_roots(struct btrfs_fs_info *fs_info, int delay_iput) | 8527 | int 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; | ||
8568 | out: | 8572 | out: |
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, | |||
1620 | static inline int btrfs_start_delalloc_flush(struct btrfs_fs_info *fs_info) | 1620 | static 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 | ||