aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/ordered-data.c
diff options
context:
space:
mode:
authorMiao Xie <miaox@cn.fujitsu.com>2012-10-25 05:31:03 -0400
committerJosef Bacik <jbacik@fusionio.com>2012-12-11 13:31:37 -0500
commit25287e0a16c0ad068aa89ab01aea6c699b31ec12 (patch)
tree3badf12a84d2e2e437fc4b432ea41c197a9cbc99 /fs/btrfs/ordered-data.c
parent8ccf6f19b67f7e0921063cc309f4672a6afcb528 (diff)
Btrfs: make ordered operations be handled by multi-task
The process of the ordered operations is similar to the delalloc inode flush, so we handle them by flush workers. Signed-off-by: Miao Xie <miaox@cn.fujitsu.com> Signed-off-by: Chris Mason <chris.mason@fusionio.com>
Diffstat (limited to 'fs/btrfs/ordered-data.c')
-rw-r--r--fs/btrfs/ordered-data.c46
1 files changed, 30 insertions, 16 deletions
diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c
index 7772f02ba28e..ab2a3c0c540f 100644
--- a/fs/btrfs/ordered-data.c
+++ b/fs/btrfs/ordered-data.c
@@ -519,13 +519,17 @@ void btrfs_wait_ordered_extents(struct btrfs_root *root, int delay_iput)
519 * extra check to make sure the ordered operation list really is empty 519 * extra check to make sure the ordered operation list really is empty
520 * before we return 520 * before we return
521 */ 521 */
522void btrfs_run_ordered_operations(struct btrfs_root *root, int wait) 522int btrfs_run_ordered_operations(struct btrfs_root *root, int wait)
523{ 523{
524 struct btrfs_inode *btrfs_inode; 524 struct btrfs_inode *btrfs_inode;
525 struct inode *inode; 525 struct inode *inode;
526 struct list_head splice; 526 struct list_head splice;
527 struct list_head works;
528 struct btrfs_delalloc_work *work, *next;
529 int ret = 0;
527 530
528 INIT_LIST_HEAD(&splice); 531 INIT_LIST_HEAD(&splice);
532 INIT_LIST_HEAD(&works);
529 533
530 mutex_lock(&root->fs_info->ordered_operations_mutex); 534 mutex_lock(&root->fs_info->ordered_operations_mutex);
531 spin_lock(&root->fs_info->ordered_extent_lock); 535 spin_lock(&root->fs_info->ordered_extent_lock);
@@ -533,6 +537,7 @@ again:
533 list_splice_init(&root->fs_info->ordered_operations, &splice); 537 list_splice_init(&root->fs_info->ordered_operations, &splice);
534 538
535 while (!list_empty(&splice)) { 539 while (!list_empty(&splice)) {
540
536 btrfs_inode = list_entry(splice.next, struct btrfs_inode, 541 btrfs_inode = list_entry(splice.next, struct btrfs_inode,
537 ordered_operations); 542 ordered_operations);
538 543
@@ -549,15 +554,26 @@ again:
549 list_add_tail(&BTRFS_I(inode)->ordered_operations, 554 list_add_tail(&BTRFS_I(inode)->ordered_operations,
550 &root->fs_info->ordered_operations); 555 &root->fs_info->ordered_operations);
551 } 556 }
557
558 if (!inode)
559 continue;
552 spin_unlock(&root->fs_info->ordered_extent_lock); 560 spin_unlock(&root->fs_info->ordered_extent_lock);
553 561
554 if (inode) { 562 work = btrfs_alloc_delalloc_work(inode, wait, 1);
555 if (wait) 563 if (!work) {
556 btrfs_wait_ordered_range(inode, 0, (u64)-1); 564 if (list_empty(&BTRFS_I(inode)->ordered_operations))
557 else 565 list_add_tail(&btrfs_inode->ordered_operations,
558 filemap_flush(inode->i_mapping); 566 &splice);
559 btrfs_add_delayed_iput(inode); 567 spin_lock(&root->fs_info->ordered_extent_lock);
568 list_splice_tail(&splice,
569 &root->fs_info->ordered_operations);
570 spin_unlock(&root->fs_info->ordered_extent_lock);
571 ret = -ENOMEM;
572 goto out;
560 } 573 }
574 list_add_tail(&work->list, &works);
575 btrfs_queue_worker(&root->fs_info->flush_workers,
576 &work->work);
561 577
562 cond_resched(); 578 cond_resched();
563 spin_lock(&root->fs_info->ordered_extent_lock); 579 spin_lock(&root->fs_info->ordered_extent_lock);
@@ -566,7 +582,13 @@ again:
566 goto again; 582 goto again;
567 583
568 spin_unlock(&root->fs_info->ordered_extent_lock); 584 spin_unlock(&root->fs_info->ordered_extent_lock);
585out:
586 list_for_each_entry_safe(work, next, &works, list) {
587 list_del_init(&work->list);
588 btrfs_wait_and_free_delalloc_work(work);
589 }
569 mutex_unlock(&root->fs_info->ordered_operations_mutex); 590 mutex_unlock(&root->fs_info->ordered_operations_mutex);
591 return ret;
570} 592}
571 593
572/* 594/*
@@ -934,15 +956,6 @@ void btrfs_add_ordered_operation(struct btrfs_trans_handle *trans,
934 if (last_mod < root->fs_info->last_trans_committed) 956 if (last_mod < root->fs_info->last_trans_committed)
935 return; 957 return;
936 958
937 /*
938 * the transaction is already committing. Just start the IO and
939 * don't bother with all of this list nonsense
940 */
941 if (trans && root->fs_info->running_transaction->blocked) {
942 btrfs_wait_ordered_range(inode, 0, (u64)-1);
943 return;
944 }
945
946 spin_lock(&root->fs_info->ordered_extent_lock); 959 spin_lock(&root->fs_info->ordered_extent_lock);
947 if (list_empty(&BTRFS_I(inode)->ordered_operations)) { 960 if (list_empty(&BTRFS_I(inode)->ordered_operations)) {
948 list_add_tail(&BTRFS_I(inode)->ordered_operations, 961 list_add_tail(&BTRFS_I(inode)->ordered_operations,
@@ -959,6 +972,7 @@ int __init ordered_data_init(void)
959 NULL); 972 NULL);
960 if (!btrfs_ordered_extent_cache) 973 if (!btrfs_ordered_extent_cache)
961 return -ENOMEM; 974 return -ENOMEM;
975
962 return 0; 976 return 0;
963} 977}
964 978