btrfs: qgroup: Make snapshot accounting work with new extent-oriented

qgroup.

Make snapshot accounting work with new extent-oriented mechanism by
skipping given root in new/old_roots in create_pending_snapshot().

Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com>
Signed-off-by: Chris Mason <clm@fb.com>
This commit is contained in:
Qu Wenruo 2015-04-20 10:09:06 +08:00 committed by Chris Mason
parent 9086db86e0
commit d672633545

View File

@ -1295,6 +1295,12 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
if (pending->error) if (pending->error)
goto no_free_objectid; goto no_free_objectid;
/*
* Make qgroup to skip current new snapshot's qgroupid, as it is
* accounted by later btrfs_qgroup_inherit().
*/
btrfs_set_skip_qgroup(trans, objectid);
btrfs_reloc_pre_snapshot(trans, pending, &to_reserve); btrfs_reloc_pre_snapshot(trans, pending, &to_reserve);
if (to_reserve > 0) { if (to_reserve > 0) {
@ -1303,7 +1309,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
to_reserve, to_reserve,
BTRFS_RESERVE_NO_FLUSH); BTRFS_RESERVE_NO_FLUSH);
if (pending->error) if (pending->error)
goto no_free_objectid; goto clear_skip_qgroup;
} }
key.objectid = objectid; key.objectid = objectid;
@ -1401,25 +1407,6 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
btrfs_abort_transaction(trans, root, ret); btrfs_abort_transaction(trans, root, ret);
goto fail; goto fail;
} }
/*
* We need to flush delayed refs in order to make sure all of our quota
* operations have been done before we call btrfs_qgroup_inherit.
*/
ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1);
if (ret) {
btrfs_abort_transaction(trans, root, ret);
goto fail;
}
ret = btrfs_qgroup_inherit(trans, fs_info,
root->root_key.objectid,
objectid, pending->inherit);
if (ret) {
btrfs_abort_transaction(trans, root, ret);
goto fail;
}
/* see comments in should_cow_block() */ /* see comments in should_cow_block() */
set_bit(BTRFS_ROOT_FORCE_COW, &root->state); set_bit(BTRFS_ROOT_FORCE_COW, &root->state);
smp_wmb(); smp_wmb();
@ -1502,11 +1489,37 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
goto fail; goto fail;
} }
} }
ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1);
if (ret) {
btrfs_abort_transaction(trans, root, ret);
goto fail;
}
/*
* account qgroup counters before qgroup_inherit()
*/
ret = btrfs_qgroup_prepare_account_extents(trans, fs_info);
if (ret)
goto fail;
ret = btrfs_qgroup_account_extents(trans, fs_info);
if (ret)
goto fail;
ret = btrfs_qgroup_inherit(trans, fs_info,
root->root_key.objectid,
objectid, pending->inherit);
if (ret) {
btrfs_abort_transaction(trans, root, ret);
goto fail;
}
fail: fail:
pending->error = ret; pending->error = ret;
dir_item_existed: dir_item_existed:
trans->block_rsv = rsv; trans->block_rsv = rsv;
trans->bytes_reserved = 0; trans->bytes_reserved = 0;
clear_skip_qgroup:
btrfs_clear_skip_qgroup(trans);
no_free_objectid: no_free_objectid:
kfree(new_root_item); kfree(new_root_item);
root_item_alloc_fail: root_item_alloc_fail: