mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-28 01:21:58 +00:00
Btrfs: make ordered extent be flushed by multi-task
Though the process of the ordered extents is a bit different with the delalloc inode flush, but we can see it as a subset of the delalloc inode flush, so we also handle them by flush workers. Signed-off-by: Miao Xie <miaox@cn.fujitsu.com> Signed-off-by: Chris Mason <chris.mason@fusionio.com>
This commit is contained in:
parent
25287e0a16
commit
9afab8820b
2 changed files with 37 additions and 9 deletions
|
@ -211,6 +211,8 @@ static int __btrfs_add_ordered_extent(struct inode *inode, u64 file_offset,
|
||||||
init_waitqueue_head(&entry->wait);
|
init_waitqueue_head(&entry->wait);
|
||||||
INIT_LIST_HEAD(&entry->list);
|
INIT_LIST_HEAD(&entry->list);
|
||||||
INIT_LIST_HEAD(&entry->root_extent_list);
|
INIT_LIST_HEAD(&entry->root_extent_list);
|
||||||
|
INIT_LIST_HEAD(&entry->work_list);
|
||||||
|
init_completion(&entry->completion);
|
||||||
|
|
||||||
trace_btrfs_ordered_extent_add(inode, entry);
|
trace_btrfs_ordered_extent_add(inode, entry);
|
||||||
|
|
||||||
|
@ -464,18 +466,28 @@ void btrfs_remove_ordered_extent(struct inode *inode,
|
||||||
wake_up(&entry->wait);
|
wake_up(&entry->wait);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void btrfs_run_ordered_extent_work(struct btrfs_work *work)
|
||||||
|
{
|
||||||
|
struct btrfs_ordered_extent *ordered;
|
||||||
|
|
||||||
|
ordered = container_of(work, struct btrfs_ordered_extent, flush_work);
|
||||||
|
btrfs_start_ordered_extent(ordered->inode, ordered, 1);
|
||||||
|
complete(&ordered->completion);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* wait for all the ordered extents in a root. This is done when balancing
|
* wait for all the ordered extents in a root. This is done when balancing
|
||||||
* space between drives.
|
* space between drives.
|
||||||
*/
|
*/
|
||||||
void btrfs_wait_ordered_extents(struct btrfs_root *root, int delay_iput)
|
void btrfs_wait_ordered_extents(struct btrfs_root *root, int delay_iput)
|
||||||
{
|
{
|
||||||
struct list_head splice;
|
struct list_head splice, works;
|
||||||
struct list_head *cur;
|
struct list_head *cur;
|
||||||
struct btrfs_ordered_extent *ordered;
|
struct btrfs_ordered_extent *ordered, *next;
|
||||||
struct inode *inode;
|
struct inode *inode;
|
||||||
|
|
||||||
INIT_LIST_HEAD(&splice);
|
INIT_LIST_HEAD(&splice);
|
||||||
|
INIT_LIST_HEAD(&works);
|
||||||
|
|
||||||
spin_lock(&root->fs_info->ordered_extent_lock);
|
spin_lock(&root->fs_info->ordered_extent_lock);
|
||||||
list_splice_init(&root->fs_info->ordered_extents, &splice);
|
list_splice_init(&root->fs_info->ordered_extents, &splice);
|
||||||
|
@ -494,19 +506,32 @@ void btrfs_wait_ordered_extents(struct btrfs_root *root, int delay_iput)
|
||||||
spin_unlock(&root->fs_info->ordered_extent_lock);
|
spin_unlock(&root->fs_info->ordered_extent_lock);
|
||||||
|
|
||||||
if (inode) {
|
if (inode) {
|
||||||
btrfs_start_ordered_extent(inode, ordered, 1);
|
ordered->flush_work.func = btrfs_run_ordered_extent_work;
|
||||||
btrfs_put_ordered_extent(ordered);
|
list_add_tail(&ordered->work_list, &works);
|
||||||
if (delay_iput)
|
btrfs_queue_worker(&root->fs_info->flush_workers,
|
||||||
btrfs_add_delayed_iput(inode);
|
&ordered->flush_work);
|
||||||
else
|
|
||||||
iput(inode);
|
|
||||||
} else {
|
} else {
|
||||||
btrfs_put_ordered_extent(ordered);
|
btrfs_put_ordered_extent(ordered);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cond_resched();
|
||||||
spin_lock(&root->fs_info->ordered_extent_lock);
|
spin_lock(&root->fs_info->ordered_extent_lock);
|
||||||
}
|
}
|
||||||
spin_unlock(&root->fs_info->ordered_extent_lock);
|
spin_unlock(&root->fs_info->ordered_extent_lock);
|
||||||
|
|
||||||
|
list_for_each_entry_safe(ordered, next, &works, work_list) {
|
||||||
|
list_del_init(&ordered->work_list);
|
||||||
|
wait_for_completion(&ordered->completion);
|
||||||
|
|
||||||
|
inode = ordered->inode;
|
||||||
|
btrfs_put_ordered_extent(ordered);
|
||||||
|
if (delay_iput)
|
||||||
|
btrfs_add_delayed_iput(inode);
|
||||||
|
else
|
||||||
|
iput(inode);
|
||||||
|
|
||||||
|
cond_resched();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -128,8 +128,11 @@ struct btrfs_ordered_extent {
|
||||||
struct list_head root_extent_list;
|
struct list_head root_extent_list;
|
||||||
|
|
||||||
struct btrfs_work work;
|
struct btrfs_work work;
|
||||||
};
|
|
||||||
|
|
||||||
|
struct completion completion;
|
||||||
|
struct btrfs_work flush_work;
|
||||||
|
struct list_head work_list;
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* calculates the total size you need to allocate for an ordered sum
|
* calculates the total size you need to allocate for an ordered sum
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue