Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 346651
b: refs/heads/master
c: 8ccf6f1
h: refs/heads/master
i:
  346649: f2c4d71
  346647: b4974ae
v: v3
  • Loading branch information
Miao Xie authored and Josef Bacik committed Dec 11, 2012
1 parent 0d2c411 commit c28e4d4
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 9 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 7b398f8e58c415738e397645c926253c428cf002
refs/heads/master: 8ccf6f19b67f7e0921063cc309f4672a6afcb528
14 changes: 14 additions & 0 deletions trunk/fs/btrfs/ctree.h
Original file line number Diff line number Diff line change
Expand Up @@ -1333,6 +1333,7 @@ struct btrfs_fs_info {
struct btrfs_workers generic_worker;
struct btrfs_workers workers;
struct btrfs_workers delalloc_workers;
struct btrfs_workers flush_workers;
struct btrfs_workers endio_workers;
struct btrfs_workers endio_meta_workers;
struct btrfs_workers endio_meta_write_workers;
Expand Down Expand Up @@ -3277,6 +3278,19 @@ int btrfs_csum_truncate(struct btrfs_trans_handle *trans,
int btrfs_lookup_csums_range(struct btrfs_root *root, u64 start, u64 end,
struct list_head *list, int search_commit);
/* inode.c */
struct btrfs_delalloc_work {
struct inode *inode;
int wait;
int delay_iput;
struct completion completion;
struct list_head list;
struct btrfs_work work;
};

struct btrfs_delalloc_work *btrfs_alloc_delalloc_work(struct inode *inode,
int wait, int delay_iput);
void btrfs_wait_and_free_delalloc_work(struct btrfs_delalloc_work *work);

struct extent_map *btrfs_get_extent_fiemap(struct inode *inode, struct page *page,
size_t pg_offset, u64 start, u64 len,
int create);
Expand Down
7 changes: 7 additions & 0 deletions trunk/fs/btrfs/disk-io.c
Original file line number Diff line number Diff line change
Expand Up @@ -2279,6 +2279,10 @@ int open_ctree(struct super_block *sb,
fs_info->thread_pool_size,
&fs_info->generic_worker);

btrfs_init_workers(&fs_info->flush_workers, "flush_delalloc",
fs_info->thread_pool_size,
&fs_info->generic_worker);

btrfs_init_workers(&fs_info->submit_workers, "submit",
min_t(u64, fs_devices->num_devices,
fs_info->thread_pool_size),
Expand Down Expand Up @@ -2350,6 +2354,7 @@ int open_ctree(struct super_block *sb,
ret |= btrfs_start_workers(&fs_info->delayed_workers);
ret |= btrfs_start_workers(&fs_info->caching_workers);
ret |= btrfs_start_workers(&fs_info->readahead_workers);
ret |= btrfs_start_workers(&fs_info->flush_workers);
if (ret) {
err = -ENOMEM;
goto fail_sb_buffer;
Expand Down Expand Up @@ -2667,6 +2672,7 @@ int open_ctree(struct super_block *sb,
btrfs_stop_workers(&fs_info->submit_workers);
btrfs_stop_workers(&fs_info->delayed_workers);
btrfs_stop_workers(&fs_info->caching_workers);
btrfs_stop_workers(&fs_info->flush_workers);
fail_alloc:
fail_iput:
btrfs_mapping_tree_free(&fs_info->mapping_tree);
Expand Down Expand Up @@ -3339,6 +3345,7 @@ int close_ctree(struct btrfs_root *root)
btrfs_stop_workers(&fs_info->delayed_workers);
btrfs_stop_workers(&fs_info->caching_workers);
btrfs_stop_workers(&fs_info->readahead_workers);
btrfs_stop_workers(&fs_info->flush_workers);

#ifdef CONFIG_BTRFS_FS_CHECK_INTEGRITY
if (btrfs_test_opt(root, CHECK_INTEGRITY))
Expand Down
78 changes: 72 additions & 6 deletions trunk/fs/btrfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ static const struct file_operations btrfs_dir_file_operations;
static struct extent_io_ops btrfs_extent_io_ops;

static struct kmem_cache *btrfs_inode_cachep;
static struct kmem_cache *btrfs_delalloc_work_cachep;
struct kmem_cache *btrfs_trans_handle_cachep;
struct kmem_cache *btrfs_transaction_cachep;
struct kmem_cache *btrfs_path_cachep;
Expand Down Expand Up @@ -7204,6 +7205,8 @@ void btrfs_destroy_cachep(void)
kmem_cache_destroy(btrfs_path_cachep);
if (btrfs_free_space_cachep)
kmem_cache_destroy(btrfs_free_space_cachep);
if (btrfs_delalloc_work_cachep)
kmem_cache_destroy(btrfs_delalloc_work_cachep);
}

int btrfs_init_cachep(void)
Expand Down Expand Up @@ -7238,6 +7241,13 @@ int btrfs_init_cachep(void)
if (!btrfs_free_space_cachep)
goto fail;

btrfs_delalloc_work_cachep = kmem_cache_create("btrfs_delalloc_work",
sizeof(struct btrfs_delalloc_work), 0,
SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD,
NULL);
if (!btrfs_delalloc_work_cachep)
goto fail;

return 0;
fail:
btrfs_destroy_cachep();
Expand Down Expand Up @@ -7448,6 +7458,49 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry,
return ret;
}

static void btrfs_run_delalloc_work(struct btrfs_work *work)
{
struct btrfs_delalloc_work *delalloc_work;

delalloc_work = container_of(work, struct btrfs_delalloc_work,
work);
if (delalloc_work->wait)
btrfs_wait_ordered_range(delalloc_work->inode, 0, (u64)-1);
else
filemap_flush(delalloc_work->inode->i_mapping);

if (delalloc_work->delay_iput)
btrfs_add_delayed_iput(delalloc_work->inode);
else
iput(delalloc_work->inode);
complete(&delalloc_work->completion);
}

struct btrfs_delalloc_work *btrfs_alloc_delalloc_work(struct inode *inode,
int wait, int delay_iput)
{
struct btrfs_delalloc_work *work;

work = kmem_cache_zalloc(btrfs_delalloc_work_cachep, GFP_NOFS);
if (!work)
return NULL;

init_completion(&work->completion);
INIT_LIST_HEAD(&work->list);
work->inode = inode;
work->wait = wait;
work->delay_iput = delay_iput;
work->work.func = btrfs_run_delalloc_work;

return work;
}

void btrfs_wait_and_free_delalloc_work(struct btrfs_delalloc_work *work)
{
wait_for_completion(&work->completion);
kmem_cache_free(btrfs_delalloc_work_cachep, work);
}

/*
* some fairly slow code that needs optimization. This walks the list
* of all the inodes with pending delalloc and forces them to disk.
Expand All @@ -7457,10 +7510,15 @@ int btrfs_start_delalloc_inodes(struct btrfs_root *root, int delay_iput)
struct list_head *head = &root->fs_info->delalloc_inodes;
struct btrfs_inode *binode;
struct inode *inode;
struct btrfs_delalloc_work *work, *next;
struct list_head works;
int ret = 0;

if (root->fs_info->sb->s_flags & MS_RDONLY)
return -EROFS;

INIT_LIST_HEAD(&works);

spin_lock(&root->fs_info->delalloc_lock);
while (!list_empty(head)) {
binode = list_entry(head->next, struct btrfs_inode,
Expand All @@ -7470,11 +7528,14 @@ int btrfs_start_delalloc_inodes(struct btrfs_root *root, int delay_iput)
list_del_init(&binode->delalloc_inodes);
spin_unlock(&root->fs_info->delalloc_lock);
if (inode) {
filemap_flush(inode->i_mapping);
if (delay_iput)
btrfs_add_delayed_iput(inode);
else
iput(inode);
work = btrfs_alloc_delalloc_work(inode, 0, delay_iput);
if (!work) {
ret = -ENOMEM;
goto out;
}
list_add_tail(&work->list, &works);
btrfs_queue_worker(&root->fs_info->flush_workers,
&work->work);
}
cond_resched();
spin_lock(&root->fs_info->delalloc_lock);
Expand All @@ -7493,7 +7554,12 @@ int btrfs_start_delalloc_inodes(struct btrfs_root *root, int delay_iput)
atomic_read(&root->fs_info->async_delalloc_pages) == 0));
}
atomic_dec(&root->fs_info->async_submit_draining);
return 0;
out:
list_for_each_entry_safe(work, next, &works, list) {
list_del_init(&work->list);
btrfs_wait_and_free_delalloc_work(work);
}
return ret;
}

static int btrfs_symlink(struct inode *dir, struct dentry *dentry,
Expand Down
6 changes: 5 additions & 1 deletion trunk/fs/btrfs/relocation.c
Original file line number Diff line number Diff line change
Expand Up @@ -4061,7 +4061,11 @@ int btrfs_relocate_block_group(struct btrfs_root *extent_root, u64 group_start)
(unsigned long long)rc->block_group->key.objectid,
(unsigned long long)rc->block_group->flags);

btrfs_start_delalloc_inodes(fs_info->tree_root, 0);
ret = btrfs_start_delalloc_inodes(fs_info->tree_root, 0);
if (ret < 0) {
err = ret;
goto out;
}
btrfs_wait_ordered_extents(fs_info->tree_root, 0);

while (1) {
Expand Down
6 changes: 5 additions & 1 deletion trunk/fs/btrfs/transaction.c
Original file line number Diff line number Diff line change
Expand Up @@ -1497,7 +1497,11 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
WARN_ON(cur_trans != trans->transaction);

if (flush_on_commit || snap_pending) {
btrfs_start_delalloc_inodes(root, 1);
ret = btrfs_start_delalloc_inodes(root, 1);
if (ret) {
btrfs_abort_transaction(trans, root, ret);
goto cleanup_transaction;
}
btrfs_wait_ordered_extents(root, 1);
}

Expand Down

0 comments on commit c28e4d4

Please sign in to comment.