return ret;
 }
 
-int btrfs_quota_enable(struct btrfs_trans_handle *trans,
-                      struct btrfs_fs_info *fs_info)
+int btrfs_quota_enable(struct btrfs_fs_info *fs_info)
 {
        struct btrfs_root *quota_root;
        struct btrfs_root *tree_root = fs_info->tree_root;
        struct btrfs_key key;
        struct btrfs_key found_key;
        struct btrfs_qgroup *qgroup = NULL;
+       struct btrfs_trans_handle *trans = NULL;
        int ret = 0;
        int slot;
 
        if (fs_info->quota_root)
                goto out;
 
+       /*
+        * 1 for quota root item
+        * 1 for BTRFS_QGROUP_STATUS item
+        *
+        * Yet we also need 2*n items for a QGROUP_INFO/QGROUP_LIMIT items
+        * per subvolume. However those are not currently reserved since it
+        * would be a lot of overkill.
+        */
+       trans = btrfs_start_transaction(tree_root, 2);
+       if (IS_ERR(trans)) {
+               ret = PTR_ERR(trans);
+               trans = NULL;
+               goto out;
+       }
+
        fs_info->qgroup_ulist = ulist_alloc(GFP_KERNEL);
        if (!fs_info->qgroup_ulist) {
                ret = -ENOMEM;
+               btrfs_abort_transaction(trans, ret);
                goto out;
        }
 
                                       BTRFS_QUOTA_TREE_OBJECTID);
        if (IS_ERR(quota_root)) {
                ret =  PTR_ERR(quota_root);
+               btrfs_abort_transaction(trans, ret);
                goto out;
        }
 
        path = btrfs_alloc_path();
        if (!path) {
                ret = -ENOMEM;
+               btrfs_abort_transaction(trans, ret);
                goto out_free_root;
        }
 
 
        ret = btrfs_insert_empty_item(trans, quota_root, path, &key,
                                      sizeof(*ptr));
-       if (ret)
+       if (ret) {
+               btrfs_abort_transaction(trans, ret);
                goto out_free_path;
+       }
 
        leaf = path->nodes[0];
        ptr = btrfs_item_ptr(leaf, path->slots[0],
        ret = btrfs_search_slot_for_read(tree_root, &key, path, 1, 0);
        if (ret > 0)
                goto out_add_root;
-       if (ret < 0)
+       if (ret < 0) {
+               btrfs_abort_transaction(trans, ret);
                goto out_free_path;
-
+       }
 
        while (1) {
                slot = path->slots[0];
                if (found_key.type == BTRFS_ROOT_REF_KEY) {
                        ret = add_qgroup_item(trans, quota_root,
                                              found_key.offset);
-                       if (ret)
+                       if (ret) {
+                               btrfs_abort_transaction(trans, ret);
                                goto out_free_path;
+                       }
 
                        qgroup = add_qgroup_rb(fs_info, found_key.offset);
                        if (IS_ERR(qgroup)) {
                                ret = PTR_ERR(qgroup);
+                               btrfs_abort_transaction(trans, ret);
                                goto out_free_path;
                        }
                }
                ret = btrfs_next_item(tree_root, path);
-               if (ret < 0)
+               if (ret < 0) {
+                       btrfs_abort_transaction(trans, ret);
                        goto out_free_path;
+               }
                if (ret)
                        break;
        }
 out_add_root:
        btrfs_release_path(path);
        ret = add_qgroup_item(trans, quota_root, BTRFS_FS_TREE_OBJECTID);
-       if (ret)
+       if (ret) {
+               btrfs_abort_transaction(trans, ret);
                goto out_free_path;
+       }
 
        qgroup = add_qgroup_rb(fs_info, BTRFS_FS_TREE_OBJECTID);
        if (IS_ERR(qgroup)) {
                ret = PTR_ERR(qgroup);
+               btrfs_abort_transaction(trans, ret);
                goto out_free_path;
        }
        spin_lock(&fs_info->qgroup_lock);
        fs_info->quota_root = quota_root;
        set_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags);
        spin_unlock(&fs_info->qgroup_lock);
+
+       ret = btrfs_commit_transaction(trans);
+       if (ret) {
+               trans = NULL;
+               goto out_free_path;
+       }
+
        ret = qgroup_rescan_init(fs_info, 0, 1);
        if (!ret) {
                qgroup_rescan_zero_tracking(fs_info);
        if (ret) {
                ulist_free(fs_info->qgroup_ulist);
                fs_info->qgroup_ulist = NULL;
+               if (trans)
+                       btrfs_end_transaction(trans);
        }
        mutex_unlock(&fs_info->qgroup_ioctl_lock);
        return ret;
 }
 
-int btrfs_quota_disable(struct btrfs_trans_handle *trans,
-                       struct btrfs_fs_info *fs_info)
+int btrfs_quota_disable(struct btrfs_fs_info *fs_info)
 {
        struct btrfs_root *quota_root;
+       struct btrfs_trans_handle *trans = NULL;
        int ret = 0;
 
        mutex_lock(&fs_info->qgroup_ioctl_lock);
        if (!fs_info->quota_root)
                goto out;
+
+       /*
+        * 1 For the root item
+        *
+        * We should also reserve enough items for the quota tree deletion in
+        * btrfs_clean_quota_tree but this is not done.
+        */
+       trans = btrfs_start_transaction(fs_info->tree_root, 1);
+       if (IS_ERR(trans)) {
+               ret = PTR_ERR(trans);
+               goto out;
+       }
+
        clear_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags);
        btrfs_qgroup_wait_for_completion(fs_info, false);
        spin_lock(&fs_info->qgroup_lock);
        btrfs_free_qgroup_config(fs_info);
 
        ret = btrfs_clean_quota_tree(trans, quota_root);
-       if (ret)
-               goto out;
+       if (ret) {
+               btrfs_abort_transaction(trans, ret);
+               goto end_trans;
+       }
 
        ret = btrfs_del_root(trans, fs_info, "a_root->root_key);
-       if (ret)
-               goto out;
+       if (ret) {
+               btrfs_abort_transaction(trans, ret);
+               goto end_trans;
+       }
 
        list_del("a_root->dirty_list);
 
        free_extent_buffer(quota_root->node);
        free_extent_buffer(quota_root->commit_root);
        kfree(quota_root);
+
+end_trans:
+       ret = btrfs_end_transaction(trans);
 out:
        mutex_unlock(&fs_info->qgroup_ioctl_lock);
        return ret;