Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 349183
b: refs/heads/master
c: 1eafa6c
h: refs/heads/master
i:
  349181: 87a23bf
  349179: 8f26cb5
  349175: 007c14a
  349167: 8da8d71
  349151: 91fbd31
  349119: 4d54a36
  349055: 9f21c93
  348927: d5027f0
  348671: a6f2f23
  348159: 2fe83f9
v: v3
  • Loading branch information
Miao Xie authored and Josef Bacik committed Jan 24, 2013
1 parent 9720460 commit 07a3f5b
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 15 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: c9f01bfe0ca411b4751d7fdbb9d602035ba52f75
refs/heads/master: 1eafa6c73791e4f312324ddad9cbcaf6a1b6052b
55 changes: 41 additions & 14 deletions trunk/fs/btrfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -7585,41 +7585,61 @@ void btrfs_wait_and_free_delalloc_work(struct btrfs_delalloc_work *work)
*/
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;
struct list_head splice;
int ret = 0;

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

INIT_LIST_HEAD(&works);

INIT_LIST_HEAD(&splice);
again:
spin_lock(&root->fs_info->delalloc_lock);
while (!list_empty(head)) {
binode = list_entry(head->next, struct btrfs_inode,
list_splice_init(&root->fs_info->delalloc_inodes, &splice);
while (!list_empty(&splice)) {
binode = list_entry(splice.next, struct btrfs_inode,
delalloc_inodes);

list_del_init(&binode->delalloc_inodes);

inode = igrab(&binode->vfs_inode);
if (!inode)
list_del_init(&binode->delalloc_inodes);
continue;

list_add_tail(&binode->delalloc_inodes,
&root->fs_info->delalloc_inodes);
spin_unlock(&root->fs_info->delalloc_lock);
if (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);

work = btrfs_alloc_delalloc_work(inode, 0, delay_iput);
if (unlikely(!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);
}
spin_unlock(&root->fs_info->delalloc_lock);

list_for_each_entry_safe(work, next, &works, list) {
list_del_init(&work->list);
btrfs_wait_and_free_delalloc_work(work);
}

spin_lock(&root->fs_info->delalloc_lock);
if (!list_empty(&root->fs_info->delalloc_inodes)) {
spin_unlock(&root->fs_info->delalloc_lock);
goto again;
}
spin_unlock(&root->fs_info->delalloc_lock);

/* the filemap_flush will queue IO into the worker threads, but
* we have to make sure the IO is actually started and that
* ordered extents get created before we return
Expand All @@ -7632,11 +7652,18 @@ 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);
}

if (!list_empty_careful(&splice)) {
spin_lock(&root->fs_info->delalloc_lock);
list_splice_tail(&splice, &root->fs_info->delalloc_inodes);
spin_unlock(&root->fs_info->delalloc_lock);
}
return ret;
}

Expand Down

0 comments on commit 07a3f5b

Please sign in to comment.