The new qgroup stuff needs the quota accounting to be run before doing
the
inherit, unfortunately they need the commit root switch to happen at a
specific
time for this to work properly. Fix this by delaying the inherit
until after we
do the qgroup accounting, and remove the inherit and accounting dance in
create_pending_snapshot. Thanks,
Signed-off-by: Josef Bacik <jba...@fb.com>
---
fs/btrfs/transaction.c | 51
++++++++++++++++++++++++++++++--------------------
fs/btrfs/transaction.h | 1 +
2 files changed, 32 insertions(+), 20 deletions(-)
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 7c7671d..aa3025a 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -1353,6 +1353,7 @@ static noinline int
create_pending_snapshot(struct btrfs_trans_handle *trans,
pending->error = btrfs_find_free_objectid(tree_root, &objectid);
if (pending->error)
goto no_free_objectid;
+ pending->objectid = objectid;
/*
* Make qgroup to skip current new snapshot's qgroupid, as it is
@@ -1559,24 +1560,6 @@ static noinline int
create_pending_snapshot(struct btrfs_trans_handle *trans,
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:
pending->error = ret;
dir_item_existed:
@@ -1599,15 +1582,35 @@ no_free_objectid:
static noinline int create_pending_snapshots(struct
btrfs_trans_handle *trans,
struct btrfs_fs_info *fs_info)
{
+ struct btrfs_pending_snapshot *pending;
+ struct list_head *head = &trans->transaction->pending_snapshots;
+ int ret = 0;
+
+ list_for_each_entry(pending, head, list) {
+ ret = create_pending_snapshot(trans, fs_info, pending);
+ if (ret)
+ break;
+ }
+ return ret;
+}
+
+static noinline int inherit_pending_snapshots(struct
btrfs_trans_handle *trans,
+ struct btrfs_fs_info *fs_info)
+{
struct btrfs_pending_snapshot *pending, *next;
struct list_head *head = &trans->transaction->pending_snapshots;
int ret = 0;
list_for_each_entry_safe(pending, next, head, list) {
+ struct btrfs_root *root = pending->root;
list_del(&pending->list);
- ret = create_pending_snapshot(trans, fs_info, pending);
- if (ret)
+ ret = btrfs_qgroup_inherit(trans, fs_info,
+ root->root_key.objectid,
+ pending->objectid, pending->inherit);