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/inode.c | |
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/inode.c')
-rw-r--r-- | fs/btrfs/inode.c | 34 |
1 files changed, 19 insertions, 15 deletions
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); |