Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9afab882 authored by Miao Xie's avatar Miao Xie Committed by Josef Bacik
Browse files

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: default avatarMiao Xie <miaox@cn.fujitsu.com>
Signed-off-by: default avatarChris Mason <chris.mason@fusionio.com>
parent 25287e0a
Loading
Loading
Loading
Loading
+33 −8
Original line number Diff line number Diff line
@@ -211,6 +211,8 @@ static int __btrfs_add_ordered_extent(struct inode *inode, u64 file_offset,
	init_waitqueue_head(&entry->wait);
	INIT_LIST_HEAD(&entry->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);

@@ -464,18 +466,28 @@ void btrfs_remove_ordered_extent(struct inode *inode,
	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
 * space between drives.
 */
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 btrfs_ordered_extent *ordered;
	struct btrfs_ordered_extent *ordered, *next;
	struct inode *inode;

	INIT_LIST_HEAD(&splice);
	INIT_LIST_HEAD(&works);

	spin_lock(&root->fs_info->ordered_extent_lock);
	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);

		if (inode) {
			btrfs_start_ordered_extent(inode, ordered, 1);
			btrfs_put_ordered_extent(ordered);
			if (delay_iput)
				btrfs_add_delayed_iput(inode);
			else
				iput(inode);
			ordered->flush_work.func = btrfs_run_ordered_extent_work;
			list_add_tail(&ordered->work_list, &works);
			btrfs_queue_worker(&root->fs_info->flush_workers,
					   &ordered->flush_work);
		} else {
			btrfs_put_ordered_extent(ordered);
		}

		cond_resched();
		spin_lock(&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();
	}
}

/*
+4 −1
Original line number Diff line number Diff line
@@ -128,8 +128,11 @@ struct btrfs_ordered_extent {
	struct list_head root_extent_list;

	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