aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/inode.c
diff options
context:
space:
mode:
authorMiao Xie <miaox@cn.fujitsu.com>2012-10-25 05:28:04 -0400
committerJosef Bacik <jbacik@fusionio.com>2012-12-11 13:31:37 -0500
commit8ccf6f19b67f7e0921063cc309f4672a6afcb528 (patch)
tree98cd76ca5dd2e7c93adc1bd363fefaa803acc824 /fs/btrfs/inode.c
parent7b398f8e58c415738e397645c926253c428cf002 (diff)
Btrfs: make delalloc inodes be flushed by multi-task
This patch introduce a new worker pool named "flush_workers", and if we want to force all the inode with pending delalloc to the disks, we can queue those inodes into the work queue of the worker pool, in this way, those inodes will be flushed by multi-task. Signed-off-by: Miao Xie <miaox@cn.fujitsu.com> Signed-off-by: Chris Mason <chris.mason@fusionio.com>
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r--fs/btrfs/inode.c78
1 files changed, 72 insertions, 6 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index db3dd4ed057f..dce9e218b845 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -71,6 +71,7 @@ static const struct file_operations btrfs_dir_file_operations;
71static struct extent_io_ops btrfs_extent_io_ops; 71static struct extent_io_ops btrfs_extent_io_ops;
72 72
73static struct kmem_cache *btrfs_inode_cachep; 73static struct kmem_cache *btrfs_inode_cachep;
74static struct kmem_cache *btrfs_delalloc_work_cachep;
74struct kmem_cache *btrfs_trans_handle_cachep; 75struct kmem_cache *btrfs_trans_handle_cachep;
75struct kmem_cache *btrfs_transaction_cachep; 76struct kmem_cache *btrfs_transaction_cachep;
76struct kmem_cache *btrfs_path_cachep; 77struct kmem_cache *btrfs_path_cachep;
@@ -7204,6 +7205,8 @@ void btrfs_destroy_cachep(void)
7204 kmem_cache_destroy(btrfs_path_cachep); 7205 kmem_cache_destroy(btrfs_path_cachep);
7205 if (btrfs_free_space_cachep) 7206 if (btrfs_free_space_cachep)
7206 kmem_cache_destroy(btrfs_free_space_cachep); 7207 kmem_cache_destroy(btrfs_free_space_cachep);
7208 if (btrfs_delalloc_work_cachep)
7209 kmem_cache_destroy(btrfs_delalloc_work_cachep);
7207} 7210}
7208 7211
7209int btrfs_init_cachep(void) 7212int btrfs_init_cachep(void)
@@ -7238,6 +7241,13 @@ int btrfs_init_cachep(void)
7238 if (!btrfs_free_space_cachep) 7241 if (!btrfs_free_space_cachep)
7239 goto fail; 7242 goto fail;
7240 7243
7244 btrfs_delalloc_work_cachep = kmem_cache_create("btrfs_delalloc_work",
7245 sizeof(struct btrfs_delalloc_work), 0,
7246 SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD,
7247 NULL);
7248 if (!btrfs_delalloc_work_cachep)
7249 goto fail;
7250
7241 return 0; 7251 return 0;
7242fail: 7252fail:
7243 btrfs_destroy_cachep(); 7253 btrfs_destroy_cachep();
@@ -7448,6 +7458,49 @@ out_notrans:
7448 return ret; 7458 return ret;
7449} 7459}
7450 7460
7461static void btrfs_run_delalloc_work(struct btrfs_work *work)
7462{
7463 struct btrfs_delalloc_work *delalloc_work;
7464
7465 delalloc_work = container_of(work, struct btrfs_delalloc_work,
7466 work);
7467 if (delalloc_work->wait)
7468 btrfs_wait_ordered_range(delalloc_work->inode, 0, (u64)-1);
7469 else
7470 filemap_flush(delalloc_work->inode->i_mapping);
7471
7472 if (delalloc_work->delay_iput)
7473 btrfs_add_delayed_iput(delalloc_work->inode);
7474 else
7475 iput(delalloc_work->inode);
7476 complete(&delalloc_work->completion);
7477}
7478
7479struct btrfs_delalloc_work *btrfs_alloc_delalloc_work(struct inode *inode,
7480 int wait, int delay_iput)
7481{
7482 struct btrfs_delalloc_work *work;
7483
7484 work = kmem_cache_zalloc(btrfs_delalloc_work_cachep, GFP_NOFS);
7485 if (!work)
7486 return NULL;
7487
7488 init_completion(&work->completion);
7489 INIT_LIST_HEAD(&work->list);
7490 work->inode = inode;
7491 work->wait = wait;
7492 work->delay_iput = delay_iput;
7493 work->work.func = btrfs_run_delalloc_work;
7494
7495 return work;
7496}
7497
7498void btrfs_wait_and_free_delalloc_work(struct btrfs_delalloc_work *work)
7499{
7500 wait_for_completion(&work->completion);
7501 kmem_cache_free(btrfs_delalloc_work_cachep, work);
7502}
7503
7451/* 7504/*
7452 * some fairly slow code that needs optimization. This walks the list 7505 * some fairly slow code that needs optimization. This walks the list
7453 * of all the inodes with pending delalloc and forces them to disk. 7506 * of all the inodes with pending delalloc and forces them to disk.
@@ -7457,10 +7510,15 @@ int btrfs_start_delalloc_inodes(struct btrfs_root *root, int delay_iput)
7457 struct list_head *head = &root->fs_info->delalloc_inodes; 7510 struct list_head *head = &root->fs_info->delalloc_inodes;
7458 struct btrfs_inode *binode; 7511 struct btrfs_inode *binode;
7459 struct inode *inode; 7512 struct inode *inode;
7513 struct btrfs_delalloc_work *work, *next;
7514 struct list_head works;
7515 int ret = 0;
7460 7516
7461 if (root->fs_info->sb->s_flags & MS_RDONLY) 7517 if (root->fs_info->sb->s_flags & MS_RDONLY)
7462 return -EROFS; 7518 return -EROFS;
7463 7519
7520 INIT_LIST_HEAD(&works);
7521
7464 spin_lock(&root->fs_info->delalloc_lock); 7522 spin_lock(&root->fs_info->delalloc_lock);
7465 while (!list_empty(head)) { 7523 while (!list_empty(head)) {
7466 binode = list_entry(head->next, struct btrfs_inode, 7524 binode = list_entry(head->next, struct btrfs_inode,
@@ -7470,11 +7528,14 @@ int btrfs_start_delalloc_inodes(struct btrfs_root *root, int delay_iput)
7470 list_del_init(&binode->delalloc_inodes); 7528 list_del_init(&binode->delalloc_inodes);
7471 spin_unlock(&root->fs_info->delalloc_lock); 7529 spin_unlock(&root->fs_info->delalloc_lock);
7472 if (inode) { 7530 if (inode) {
7473 filemap_flush(inode->i_mapping); 7531 work = btrfs_alloc_delalloc_work(inode, 0, delay_iput);
7474 if (delay_iput) 7532 if (!work) {
7475 btrfs_add_delayed_iput(inode); 7533 ret = -ENOMEM;
7476 else 7534 goto out;
7477 iput(inode); 7535 }
7536 list_add_tail(&work->list, &works);
7537 btrfs_queue_worker(&root->fs_info->flush_workers,
7538 &work->work);
7478 } 7539 }
7479 cond_resched(); 7540 cond_resched();
7480 spin_lock(&root->fs_info->delalloc_lock); 7541 spin_lock(&root->fs_info->delalloc_lock);
@@ -7493,7 +7554,12 @@ int btrfs_start_delalloc_inodes(struct btrfs_root *root, int delay_iput)
7493 atomic_read(&root->fs_info->async_delalloc_pages) == 0)); 7554 atomic_read(&root->fs_info->async_delalloc_pages) == 0));
7494 } 7555 }
7495 atomic_dec(&root->fs_info->async_submit_draining); 7556 atomic_dec(&root->fs_info->async_submit_draining);
7496 return 0; 7557out:
7558 list_for_each_entry_safe(work, next, &works, list) {
7559 list_del_init(&work->list);
7560 btrfs_wait_and_free_delalloc_work(work);
7561 }
7562 return ret;
7497} 7563}
7498 7564
7499static int btrfs_symlink(struct inode *dir, struct dentry *dentry, 7565static int btrfs_symlink(struct inode *dir, struct dentry *dentry,