예제 #1
0
static struct btrfs_trans_handle *start_transaction(struct btrfs_root *root,
					     int num_blocks, int wait)
{
	struct btrfs_trans_handle *h =
		kmem_cache_alloc(btrfs_trans_handle_cachep, GFP_NOFS);
	int ret;

	mutex_lock(&root->fs_info->trans_mutex);
	if (!root->fs_info->log_root_recovering &&
	    ((wait == 1 && !root->fs_info->open_ioctl_trans) || wait == 2))
		wait_current_trans(root);
	ret = join_transaction(root);
	BUG_ON(ret);

	h->transid = root->fs_info->running_transaction->transid;
	h->transaction = root->fs_info->running_transaction;
	h->blocks_reserved = num_blocks;
	h->blocks_used = 0;
	h->block_group = 0;
	h->alloc_exclude_nr = 0;
	h->alloc_exclude_start = 0;
	h->delayed_ref_updates = 0;

	if (!current->journal_info)
		current->journal_info = h;

	root->fs_info->running_transaction->use_count++;
	record_root_in_trans(h, root);
	mutex_unlock(&root->fs_info->trans_mutex);
	return h;
}
예제 #2
0
static struct btrfs_trans_handle *start_transaction(struct btrfs_root *root,
        u64 num_items, int type)
{
    struct btrfs_trans_handle *h;
    struct btrfs_transaction *cur_trans;
    int retries = 0;
    int ret;
again:
    h = kmem_cache_alloc(btrfs_trans_handle_cachep, GFP_NOFS);
    if (!h)
        return ERR_PTR(-ENOMEM);

    mutex_lock(&root->fs_info->trans_mutex);
    if (may_wait_transaction(root, type))
        wait_current_trans(root);

    ret = join_transaction(root);
    BUG_ON(ret);

    cur_trans = root->fs_info->running_transaction;
    cur_trans->use_count++;
    mutex_unlock(&root->fs_info->trans_mutex);

    h->transid = cur_trans->transid;
    h->transaction = cur_trans;
    h->blocks_used = 0;
    h->block_group = 0;
    h->bytes_reserved = 0;
    h->delayed_ref_updates = 0;
    h->block_rsv = NULL;

    smp_mb();
    if (cur_trans->blocked && may_wait_transaction(root, type)) {
        btrfs_commit_transaction(h, root);
        goto again;
    }

    if (num_items > 0) {
        ret = btrfs_trans_reserve_metadata(h, root, num_items,
                                           &retries);
        if (ret == -EAGAIN) {
            btrfs_commit_transaction(h, root);
            goto again;
        }
        if (ret < 0) {
            btrfs_end_transaction(h, root);
            return ERR_PTR(ret);
        }
    }

    mutex_lock(&root->fs_info->trans_mutex);
    record_root_in_trans(h, root);
    mutex_unlock(&root->fs_info->trans_mutex);

    if (!current->journal_info && type != TRANS_USERSPACE)
        current->journal_info = h;
    return h;
}