btrfs: fix invalid delayed ref after subvolume creation failure
[sfrench/cifs-2.6.git] / fs / btrfs / extent-tree.c
index fc4895e6a62cd18ca6110b3c87d1874d47d237f0..25ef6e3fd3069f7b113be393fac05bc83c9c8295 100644 (file)
@@ -3275,20 +3275,20 @@ out_delayed_unlock:
 }
 
 void btrfs_free_tree_block(struct btrfs_trans_handle *trans,
-                          struct btrfs_root *root,
+                          u64 root_id,
                           struct extent_buffer *buf,
                           u64 parent, int last_ref)
 {
-       struct btrfs_fs_info *fs_info = root->fs_info;
+       struct btrfs_fs_info *fs_info = trans->fs_info;
        struct btrfs_ref generic_ref = { 0 };
        int ret;
 
        btrfs_init_generic_ref(&generic_ref, BTRFS_DROP_DELAYED_REF,
                               buf->start, buf->len, parent);
        btrfs_init_tree_ref(&generic_ref, btrfs_header_level(buf),
-                           root->root_key.objectid, 0, false);
+                           root_id, 0, false);
 
-       if (root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID) {
+       if (root_id != BTRFS_TREE_LOG_OBJECTID) {
                btrfs_ref_tree_mod(fs_info, &generic_ref);
                ret = btrfs_add_delayed_tree_ref(trans, &generic_ref, NULL);
                BUG_ON(ret); /* -ENOMEM */
@@ -3298,7 +3298,7 @@ void btrfs_free_tree_block(struct btrfs_trans_handle *trans,
                struct btrfs_block_group *cache;
                bool must_pin = false;
 
-               if (root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID) {
+               if (root_id != BTRFS_TREE_LOG_OBJECTID) {
                        ret = check_ref_cleanup(trans, buf->start);
                        if (!ret) {
                                btrfs_redirty_list_add(trans->transaction, buf);
@@ -5472,7 +5472,8 @@ static noinline int walk_up_proc(struct btrfs_trans_handle *trans,
                        goto owner_mismatch;
        }
 
-       btrfs_free_tree_block(trans, root, eb, parent, wc->refs[level] == 1);
+       btrfs_free_tree_block(trans, btrfs_root_id(root), eb, parent,
+                             wc->refs[level] == 1);
 out:
        wc->refs[level] = 0;
        wc->flags[level] = 0;