/*
 * defrag a given btree.  If cacheonly == 1, this won't read from the disk,
 * otherwise every leaf in the btree is read and defragged.
 */
int btrfs_defrag_root(struct btrfs_root *root, int cacheonly)
{
	struct btrfs_fs_info *info = root->fs_info;
	int ret;
	struct btrfs_trans_handle *trans;
	unsigned long nr;

	smp_mb();
	if (root->defrag_running)
		return 0;
	trans = btrfs_start_transaction(root, 1);
	while (1) {
		root->defrag_running = 1;
		ret = btrfs_defrag_leaves(trans, root, cacheonly);
		nr = trans->blocks_used;
		btrfs_end_transaction(trans, root);
		btrfs_btree_balance_dirty(info->tree_root, nr);
		cond_resched();

		trans = btrfs_start_transaction(root, 1);
		if (root->fs_info->closing || ret != -EAGAIN)
			break;
	}
	root->defrag_running = 0;
	smp_mb();
	btrfs_end_transaction(trans, root);
	return 0;
}
Example #2
0
int btrfs_defrag_root(struct btrfs_root *root, int cacheonly)
{
    struct btrfs_fs_info *info = root->fs_info;
    struct btrfs_trans_handle *trans;
    int ret;
    unsigned long nr;

    if (xchg(&root->defrag_running, 1))
        return 0;

    while (1) {
        trans = btrfs_start_transaction(root, 0);
        if (IS_ERR(trans))
            return PTR_ERR(trans);

        ret = btrfs_defrag_leaves(trans, root, cacheonly);

        nr = trans->blocks_used;
        btrfs_end_transaction(trans, root);
        btrfs_btree_balance_dirty(info->tree_root, nr);
        cond_resched();

        if (root->fs_info->closing || ret != -EAGAIN)
            break;
    }
    root->defrag_running = 0;
    return ret;
}