btrfs: annotate unlikely branches after V0 extent type removal
[sfrench/cifs-2.6.git] / fs / btrfs / extent-tree.c
index c0928fcb3f32877db32a8911b74ab87a7f666545..352b7e95f657f57fb3ced71563c81aacb0682ff9 100644 (file)
@@ -217,9 +217,9 @@ static int add_excluded_extent(struct btrfs_fs_info *fs_info,
        return 0;
 }
 
-static void free_excluded_extents(struct btrfs_fs_info *fs_info,
-                                 struct btrfs_block_group_cache *cache)
+static void free_excluded_extents(struct btrfs_block_group_cache *cache)
 {
+       struct btrfs_fs_info *fs_info = cache->fs_info;
        u64 start, end;
 
        start = cache->key.objectid;
@@ -231,9 +231,9 @@ static void free_excluded_extents(struct btrfs_fs_info *fs_info,
                          start, end, EXTENT_UPTODATE);
 }
 
-static int exclude_super_stripes(struct btrfs_fs_info *fs_info,
-                                struct btrfs_block_group_cache *cache)
+static int exclude_super_stripes(struct btrfs_block_group_cache *cache)
 {
+       struct btrfs_fs_info *fs_info = cache->fs_info;
        u64 bytenr;
        u64 *logical;
        int stripe_len;
@@ -555,7 +555,7 @@ static noinline void caching_thread(struct btrfs_work *work)
        caching_ctl->progress = (u64)-1;
 
        up_read(&fs_info->commit_root_sem);
-       free_excluded_extents(fs_info, block_group);
+       free_excluded_extents(block_group);
        mutex_unlock(&caching_ctl->mutex);
 
        wake_up(&caching_ctl->wait);
@@ -663,7 +663,7 @@ static int cache_block_group(struct btrfs_block_group_cache *cache,
                wake_up(&caching_ctl->wait);
                if (ret == 1) {
                        put_caching_control(caching_ctl);
-                       free_excluded_extents(fs_info, cache);
+                       free_excluded_extents(cache);
                        return 0;
                }
        } else {
@@ -867,18 +867,16 @@ search_again:
                        num_refs = btrfs_extent_refs(leaf, ei);
                        extent_flags = btrfs_extent_flags(leaf, ei);
                } else {
-#ifdef BTRFS_COMPAT_EXTENT_TREE_V0
-                       struct btrfs_extent_item_v0 *ei0;
-                       BUG_ON(item_size != sizeof(*ei0));
-                       ei0 = btrfs_item_ptr(leaf, path->slots[0],
-                                            struct btrfs_extent_item_v0);
-                       num_refs = btrfs_extent_refs_v0(leaf, ei0);
-                       /* FIXME: this isn't correct for data */
-                       extent_flags = BTRFS_BLOCK_FLAG_FULL_BACKREF;
-#else
-                       BUG();
-#endif
+                       ret = -EINVAL;
+                       btrfs_print_v0_err(fs_info);
+                       if (trans)
+                               btrfs_abort_transaction(trans, ret);
+                       else
+                               btrfs_handle_fs_error(fs_info, ret, NULL);
+
+                       goto out_free;
                }
+
                BUG_ON(num_refs == 0);
        } else {
                num_refs = 0;
@@ -1036,89 +1034,6 @@ out_free:
  * tree block info structure.
  */
 
-#ifdef BTRFS_COMPAT_EXTENT_TREE_V0
-static int convert_extent_item_v0(struct btrfs_trans_handle *trans,
-                                 struct btrfs_fs_info *fs_info,
-                                 struct btrfs_path *path,
-                                 u64 owner, u32 extra_size)
-{
-       struct btrfs_root *root = fs_info->extent_root;
-       struct btrfs_extent_item *item;
-       struct btrfs_extent_item_v0 *ei0;
-       struct btrfs_extent_ref_v0 *ref0;
-       struct btrfs_tree_block_info *bi;
-       struct extent_buffer *leaf;
-       struct btrfs_key key;
-       struct btrfs_key found_key;
-       u32 new_size = sizeof(*item);
-       u64 refs;
-       int ret;
-
-       leaf = path->nodes[0];
-       BUG_ON(btrfs_item_size_nr(leaf, path->slots[0]) != sizeof(*ei0));
-
-       btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
-       ei0 = btrfs_item_ptr(leaf, path->slots[0],
-                            struct btrfs_extent_item_v0);
-       refs = btrfs_extent_refs_v0(leaf, ei0);
-
-       if (owner == (u64)-1) {
-               while (1) {
-                       if (path->slots[0] >= btrfs_header_nritems(leaf)) {
-                               ret = btrfs_next_leaf(root, path);
-                               if (ret < 0)
-                                       return ret;
-                               BUG_ON(ret > 0); /* Corruption */
-                               leaf = path->nodes[0];
-                       }
-                       btrfs_item_key_to_cpu(leaf, &found_key,
-                                             path->slots[0]);
-                       BUG_ON(key.objectid != found_key.objectid);
-                       if (found_key.type != BTRFS_EXTENT_REF_V0_KEY) {
-                               path->slots[0]++;
-                               continue;
-                       }
-                       ref0 = btrfs_item_ptr(leaf, path->slots[0],
-                                             struct btrfs_extent_ref_v0);
-                       owner = btrfs_ref_objectid_v0(leaf, ref0);
-                       break;
-               }
-       }
-       btrfs_release_path(path);
-
-       if (owner < BTRFS_FIRST_FREE_OBJECTID)
-               new_size += sizeof(*bi);
-
-       new_size -= sizeof(*ei0);
-       ret = btrfs_search_slot(trans, root, &key, path,
-                               new_size + extra_size, 1);
-       if (ret < 0)
-               return ret;
-       BUG_ON(ret); /* Corruption */
-
-       btrfs_extend_item(fs_info, path, new_size);
-
-       leaf = path->nodes[0];
-       item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_extent_item);
-       btrfs_set_extent_refs(leaf, item, refs);
-       /* FIXME: get real generation */
-       btrfs_set_extent_generation(leaf, item, 0);
-       if (owner < BTRFS_FIRST_FREE_OBJECTID) {
-               btrfs_set_extent_flags(leaf, item,
-                                      BTRFS_EXTENT_FLAG_TREE_BLOCK |
-                                      BTRFS_BLOCK_FLAG_FULL_BACKREF);
-               bi = (struct btrfs_tree_block_info *)(item + 1);
-               /* FIXME: get first key of the block */
-               memzero_extent_buffer(leaf, (unsigned long)bi, sizeof(*bi));
-               btrfs_set_tree_block_level(leaf, bi, (int)owner);
-       } else {
-               btrfs_set_extent_flags(leaf, item, BTRFS_EXTENT_FLAG_DATA);
-       }
-       btrfs_mark_buffer_dirty(leaf);
-       return 0;
-}
-#endif
-
 /*
  * is_data == BTRFS_REF_TYPE_BLOCK, tree block type is required,
  * is_data == BTRFS_REF_TYPE_DATA, data type is requried,
@@ -1247,17 +1162,6 @@ again:
        if (parent) {
                if (!ret)
                        return 0;
-#ifdef BTRFS_COMPAT_EXTENT_TREE_V0
-               key.type = BTRFS_EXTENT_REF_V0_KEY;
-               btrfs_release_path(path);
-               ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
-               if (ret < 0) {
-                       err = ret;
-                       goto fail;
-               }
-               if (!ret)
-                       return 0;
-#endif
                goto fail;
        }
 
@@ -1400,13 +1304,10 @@ static noinline int remove_extent_data_ref(struct btrfs_trans_handle *trans,
                ref2 = btrfs_item_ptr(leaf, path->slots[0],
                                      struct btrfs_shared_data_ref);
                num_refs = btrfs_shared_data_ref_count(leaf, ref2);
-#ifdef BTRFS_COMPAT_EXTENT_TREE_V0
-       } else if (key.type == BTRFS_EXTENT_REF_V0_KEY) {
-               struct btrfs_extent_ref_v0 *ref0;
-               ref0 = btrfs_item_ptr(leaf, path->slots[0],
-                                     struct btrfs_extent_ref_v0);
-               num_refs = btrfs_ref_count_v0(leaf, ref0);
-#endif
+       } else if (unlikely(key.type == BTRFS_EXTENT_REF_V0_KEY)) {
+               btrfs_print_v0_err(trans->fs_info);
+               btrfs_abort_transaction(trans, -EINVAL);
+               return -EINVAL;
        } else {
                BUG();
        }
@@ -1422,14 +1323,6 @@ static noinline int remove_extent_data_ref(struct btrfs_trans_handle *trans,
                        btrfs_set_extent_data_ref_count(leaf, ref1, num_refs);
                else if (key.type == BTRFS_SHARED_DATA_REF_KEY)
                        btrfs_set_shared_data_ref_count(leaf, ref2, num_refs);
-#ifdef BTRFS_COMPAT_EXTENT_TREE_V0
-               else {
-                       struct btrfs_extent_ref_v0 *ref0;
-                       ref0 = btrfs_item_ptr(leaf, path->slots[0],
-                                       struct btrfs_extent_ref_v0);
-                       btrfs_set_ref_count_v0(leaf, ref0, num_refs);
-               }
-#endif
                btrfs_mark_buffer_dirty(leaf);
        }
        return ret;
@@ -1447,6 +1340,8 @@ static noinline u32 extent_data_ref_count(struct btrfs_path *path,
 
        leaf = path->nodes[0];
        btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
+
+       BUG_ON(key.type == BTRFS_EXTENT_REF_V0_KEY);
        if (iref) {
                /*
                 * If type is invalid, we should have bailed out earlier than
@@ -1469,13 +1364,6 @@ static noinline u32 extent_data_ref_count(struct btrfs_path *path,
                ref2 = btrfs_item_ptr(leaf, path->slots[0],
                                      struct btrfs_shared_data_ref);
                num_refs = btrfs_shared_data_ref_count(leaf, ref2);
-#ifdef BTRFS_COMPAT_EXTENT_TREE_V0
-       } else if (key.type == BTRFS_EXTENT_REF_V0_KEY) {
-               struct btrfs_extent_ref_v0 *ref0;
-               ref0 = btrfs_item_ptr(leaf, path->slots[0],
-                                     struct btrfs_extent_ref_v0);
-               num_refs = btrfs_ref_count_v0(leaf, ref0);
-#endif
        } else {
                WARN_ON(1);
        }
@@ -1503,15 +1391,6 @@ static noinline int lookup_tree_block_ref(struct btrfs_trans_handle *trans,
        ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
        if (ret > 0)
                ret = -ENOENT;
-#ifdef BTRFS_COMPAT_EXTENT_TREE_V0
-       if (ret == -ENOENT && parent) {
-               btrfs_release_path(path);
-               key.type = BTRFS_EXTENT_REF_V0_KEY;
-               ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
-               if (ret > 0)
-                       ret = -ENOENT;
-       }
-#endif
        return ret;
 }
 
@@ -1676,23 +1555,12 @@ again:
 
        leaf = path->nodes[0];
        item_size = btrfs_item_size_nr(leaf, path->slots[0]);
-#ifdef BTRFS_COMPAT_EXTENT_TREE_V0
-       if (item_size < sizeof(*ei)) {
-               if (!insert) {
-                       err = -ENOENT;
-                       goto out;
-               }
-               ret = convert_extent_item_v0(trans, fs_info, path, owner,
-                                            extra_size);
-               if (ret < 0) {
-                       err = ret;
-                       goto out;
-               }
-               leaf = path->nodes[0];
-               item_size = btrfs_item_size_nr(leaf, path->slots[0]);
+       if (unlikely(item_size < sizeof(*ei))) {
+               err = -EINVAL;
+               btrfs_print_v0_err(fs_info);
+               btrfs_abort_transaction(trans, err);
+               goto out;
        }
-#endif
-       BUG_ON(item_size < sizeof(*ei));
 
        ei = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_extent_item);
        flags = btrfs_extent_flags(leaf, ei);
@@ -1719,7 +1587,7 @@ again:
                iref = (struct btrfs_extent_inline_ref *)ptr;
                type = btrfs_get_extent_inline_ref_type(leaf, iref, needed);
                if (type == BTRFS_REF_TYPE_INVALID) {
-                       err = -EINVAL;
+                       err = -EUCLEAN;
                        goto out;
                }
 
@@ -1954,7 +1822,6 @@ void update_inline_extent_backref(struct btrfs_path *path,
 
 static noinline_for_stack
 int insert_inline_extent_backref(struct btrfs_trans_handle *trans,
-                                struct btrfs_fs_info *fs_info,
                                 struct btrfs_path *path,
                                 u64 bytenr, u64 num_bytes, u64 parent,
                                 u64 root_objectid, u64 owner,
@@ -1972,7 +1839,7 @@ int insert_inline_extent_backref(struct btrfs_trans_handle *trans,
                update_inline_extent_backref(path, iref, refs_to_add,
                                             extent_op, NULL);
        } else if (ret == -ENOENT) {
-               setup_inline_extent_backref(fs_info, path, iref, parent,
+               setup_inline_extent_backref(trans->fs_info, path, iref, parent,
                                            root_objectid, owner, offset,
                                            refs_to_add, extent_op);
                ret = 0;
@@ -1999,7 +1866,6 @@ static int insert_extent_backref(struct btrfs_trans_handle *trans,
 }
 
 static int remove_extent_backref(struct btrfs_trans_handle *trans,
-                                struct btrfs_fs_info *fs_info,
                                 struct btrfs_path *path,
                                 struct btrfs_extent_inline_ref *iref,
                                 int refs_to_drop, int is_data, int *last_ref)
@@ -2015,7 +1881,7 @@ static int remove_extent_backref(struct btrfs_trans_handle *trans,
                                             last_ref);
        } else {
                *last_ref = 1;
-               ret = btrfs_del_item(trans, fs_info->extent_root, path);
+               ret = btrfs_del_item(trans, trans->fs_info->extent_root, path);
        }
        return ret;
 }
@@ -2235,7 +2101,6 @@ static int __btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
                                  u64 owner, u64 offset, int refs_to_add,
                                  struct btrfs_delayed_extent_op *extent_op)
 {
-       struct btrfs_fs_info *fs_info = trans->fs_info;
        struct btrfs_path *path;
        struct extent_buffer *leaf;
        struct btrfs_extent_item *item;
@@ -2252,10 +2117,9 @@ static int __btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
        path->reada = READA_FORWARD;
        path->leave_spinning = 1;
        /* this will setup the path even if it fails to insert the back ref */
-       ret = insert_inline_extent_backref(trans, fs_info, path, bytenr,
-                                          num_bytes, parent, root_objectid,
-                                          owner, offset,
-                                          refs_to_add, extent_op);
+       ret = insert_inline_extent_backref(trans, path, bytenr, num_bytes,
+                                          parent, root_objectid, owner,
+                                          offset, refs_to_add, extent_op);
        if ((ret < 0 && ret != -EAGAIN) || !ret)
                goto out;
 
@@ -2420,18 +2284,14 @@ again:
 
        leaf = path->nodes[0];
        item_size = btrfs_item_size_nr(leaf, path->slots[0]);
-#ifdef BTRFS_COMPAT_EXTENT_TREE_V0
-       if (item_size < sizeof(*ei)) {
-               ret = convert_extent_item_v0(trans, fs_info, path, (u64)-1, 0);
-               if (ret < 0) {
-                       err = ret;
-                       goto out;
-               }
-               leaf = path->nodes[0];
-               item_size = btrfs_item_size_nr(leaf, path->slots[0]);
+
+       if (unlikely(item_size < sizeof(*ei))) {
+               err = -EINVAL;
+               btrfs_print_v0_err(fs_info);
+               btrfs_abort_transaction(trans, err);
+               goto out;
        }
-#endif
-       BUG_ON(item_size < sizeof(*ei));
+
        ei = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_extent_item);
        __run_delayed_extent_op(extent_op, leaf, ei);
 
@@ -2482,7 +2342,6 @@ static int run_delayed_tree_ref(struct btrfs_trans_handle *trans,
 
 /* helper function to actually process a single delayed ref entry */
 static int run_one_delayed_ref(struct btrfs_trans_handle *trans,
-                              struct btrfs_fs_info *fs_info,
                               struct btrfs_delayed_ref_node *node,
                               struct btrfs_delayed_extent_op *extent_op,
                               int insert_reserved)
@@ -2491,7 +2350,7 @@ static int run_one_delayed_ref(struct btrfs_trans_handle *trans,
 
        if (trans->aborted) {
                if (insert_reserved)
-                       btrfs_pin_extent(fs_info, node->bytenr,
+                       btrfs_pin_extent(trans->fs_info, node->bytenr,
                                         node->num_bytes, 1);
                return 0;
        }
@@ -2768,7 +2627,7 @@ static noinline int __btrfs_run_delayed_refs(struct btrfs_trans_handle *trans,
                locked_ref->extent_op = NULL;
                spin_unlock(&locked_ref->lock);
 
-               ret = run_one_delayed_ref(trans, fs_info, ref, extent_op,
+               ret = run_one_delayed_ref(trans, ref, extent_op,
                                          must_insert_reserved);
 
                btrfs_free_delayed_extent_op(extent_op);
@@ -3243,12 +3102,6 @@ static noinline int check_committed_ref(struct btrfs_root *root,
 
        ret = 1;
        item_size = btrfs_item_size_nr(leaf, path->slots[0]);
-#ifdef BTRFS_COMPAT_EXTENT_TREE_V0
-       if (item_size < sizeof(*ei)) {
-               WARN_ON(item_size != sizeof(struct btrfs_extent_item_v0));
-               goto out;
-       }
-#endif
        ei = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_extent_item);
 
        if (item_size != sizeof(*ei) +
@@ -4527,9 +4380,9 @@ static u64 get_profile_num_devs(struct btrfs_fs_info *fs_info, u64 type)
  * for allocating a chunk, otherwise if it's false, reserve space necessary for
  * removing a chunk.
  */
-void check_system_chunk(struct btrfs_trans_handle *trans,
-                       struct btrfs_fs_info *fs_info, u64 type)
+void check_system_chunk(struct btrfs_trans_handle *trans, u64 type)
 {
+       struct btrfs_fs_info *fs_info = trans->fs_info;
        struct btrfs_space_info *info;
        u64 left;
        u64 thresh;
@@ -4668,7 +4521,7 @@ again:
         * Check if we have enough space in SYSTEM chunk because we may need
         * to update devices.
         */
-       check_system_chunk(trans, fs_info, flags);
+       check_system_chunk(trans, flags);
 
        ret = btrfs_alloc_chunk(trans, flags);
        trans->allocating_chunk = false;
@@ -6893,14 +6746,10 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
                                break;
                        extent_slot--;
                }
-#ifdef BTRFS_COMPAT_EXTENT_TREE_V0
-               item_size = btrfs_item_size_nr(path->nodes[0], extent_slot);
-               if (found_extent && item_size < sizeof(*ei))
-                       found_extent = 0;
-#endif
+
                if (!found_extent) {
                        BUG_ON(iref);
-                       ret = remove_extent_backref(trans, info, path, NULL,
+                       ret = remove_extent_backref(trans, path, NULL,
                                                    refs_to_drop,
                                                    is_data, &last_ref);
                        if (ret) {
@@ -6973,42 +6822,12 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
 
        leaf = path->nodes[0];
        item_size = btrfs_item_size_nr(leaf, extent_slot);
-#ifdef BTRFS_COMPAT_EXTENT_TREE_V0
-       if (item_size < sizeof(*ei)) {
-               BUG_ON(found_extent || extent_slot != path->slots[0]);
-               ret = convert_extent_item_v0(trans, info, path, owner_objectid,
-                                            0);
-               if (ret < 0) {
-                       btrfs_abort_transaction(trans, ret);
-                       goto out;
-               }
-
-               btrfs_release_path(path);
-               path->leave_spinning = 1;
-
-               key.objectid = bytenr;
-               key.type = BTRFS_EXTENT_ITEM_KEY;
-               key.offset = num_bytes;
-
-               ret = btrfs_search_slot(trans, extent_root, &key, path,
-                                       -1, 1);
-               if (ret) {
-                       btrfs_err(info,
-                                 "umm, got %d back from search, was looking for %llu",
-                               ret, bytenr);
-                       btrfs_print_leaf(path->nodes[0]);
-               }
-               if (ret < 0) {
-                       btrfs_abort_transaction(trans, ret);
-                       goto out;
-               }
-
-               extent_slot = path->slots[0];
-               leaf = path->nodes[0];
-               item_size = btrfs_item_size_nr(leaf, extent_slot);
+       if (unlikely(item_size < sizeof(*ei))) {
+               ret = -EINVAL;
+               btrfs_print_v0_err(info);
+               btrfs_abort_transaction(trans, ret);
+               goto out;
        }
-#endif
-       BUG_ON(item_size < sizeof(*ei));
        ei = btrfs_item_ptr(leaf, extent_slot,
                            struct btrfs_extent_item);
        if (owner_objectid < BTRFS_FIRST_FREE_OBJECTID &&
@@ -7044,9 +6863,9 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
                        btrfs_mark_buffer_dirty(leaf);
                }
                if (found_extent) {
-                       ret = remove_extent_backref(trans, info, path,
-                                                   iref, refs_to_drop,
-                                                   is_data, &last_ref);
+                       ret = remove_extent_backref(trans, path, iref,
+                                                   refs_to_drop, is_data,
+                                                   &last_ref);
                        if (ret) {
                                btrfs_abort_transaction(trans, ret);
                                goto out;
@@ -8268,10 +8087,10 @@ int btrfs_alloc_reserved_file_extent(struct btrfs_trans_handle *trans,
  * space cache bits as well
  */
 int btrfs_alloc_logged_file_extent(struct btrfs_trans_handle *trans,
-                                  struct btrfs_fs_info *fs_info,
                                   u64 root_objectid, u64 owner, u64 offset,
                                   struct btrfs_key *ins)
 {
+       struct btrfs_fs_info *fs_info = trans->fs_info;
        int ret;
        struct btrfs_block_group_cache *block_group;
        struct btrfs_space_info *space_info;
@@ -8307,7 +8126,7 @@ int btrfs_alloc_logged_file_extent(struct btrfs_trans_handle *trans,
 
 static struct extent_buffer *
 btrfs_init_new_buffer(struct btrfs_trans_handle *trans, struct btrfs_root *root,
-                     u64 bytenr, int level)
+                     u64 bytenr, int level, u64 owner)
 {
        struct btrfs_fs_info *fs_info = root->fs_info;
        struct extent_buffer *buf;
@@ -8316,7 +8135,6 @@ btrfs_init_new_buffer(struct btrfs_trans_handle *trans, struct btrfs_root *root,
        if (IS_ERR(buf))
                return buf;
 
-       btrfs_set_header_generation(buf, trans->transid);
        btrfs_set_buffer_lockdep_class(root->root_key.objectid, buf, level);
        btrfs_tree_lock(buf);
        clean_tree_block(fs_info, buf);
@@ -8325,6 +8143,14 @@ btrfs_init_new_buffer(struct btrfs_trans_handle *trans, struct btrfs_root *root,
        btrfs_set_lock_blocking(buf);
        set_extent_buffer_uptodate(buf);
 
+       memzero_extent_buffer(buf, 0, sizeof(struct btrfs_header));
+       btrfs_set_header_level(buf, level);
+       btrfs_set_header_bytenr(buf, buf->start);
+       btrfs_set_header_generation(buf, trans->transid);
+       btrfs_set_header_backref_rev(buf, BTRFS_MIXED_BACKREF_REV);
+       btrfs_set_header_owner(buf, owner);
+       write_extent_buffer_fsid(buf, fs_info->fsid);
+       write_extent_buffer_chunk_tree_uuid(buf, fs_info->chunk_tree_uuid);
        if (root->root_key.objectid == BTRFS_TREE_LOG_OBJECTID) {
                buf->log_index = root->log_transid % 2;
                /*
@@ -8433,7 +8259,7 @@ struct extent_buffer *btrfs_alloc_tree_block(struct btrfs_trans_handle *trans,
 #ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS
        if (btrfs_is_testing(fs_info)) {
                buf = btrfs_init_new_buffer(trans, root, root->alloc_bytenr,
-                                           level);
+                                           level, root_objectid);
                if (!IS_ERR(buf))
                        root->alloc_bytenr += blocksize;
                return buf;
@@ -8449,7 +8275,8 @@ struct extent_buffer *btrfs_alloc_tree_block(struct btrfs_trans_handle *trans,
        if (ret)
                goto out_unuse;
 
-       buf = btrfs_init_new_buffer(trans, root, ins.objectid, level);
+       buf = btrfs_init_new_buffer(trans, root, ins.objectid, level,
+                                   root_objectid);
        if (IS_ERR(buf)) {
                ret = PTR_ERR(buf);
                goto out_free_reserved;
@@ -9431,10 +9258,10 @@ out:
        return ret;
 }
 
-int btrfs_inc_block_group_ro(struct btrfs_fs_info *fs_info,
-                            struct btrfs_block_group_cache *cache)
+int btrfs_inc_block_group_ro(struct btrfs_block_group_cache *cache)
 
 {
+       struct btrfs_fs_info *fs_info = cache->fs_info;
        struct btrfs_trans_handle *trans;
        u64 alloc_flags;
        int ret;
@@ -9493,7 +9320,7 @@ out:
        if (cache->flags & BTRFS_BLOCK_GROUP_SYSTEM) {
                alloc_flags = update_block_group_flags(fs_info, cache->flags);
                mutex_lock(&fs_info->chunk_mutex);
-               check_system_chunk(trans, fs_info, alloc_flags);
+               check_system_chunk(trans, alloc_flags);
                mutex_unlock(&fs_info->chunk_mutex);
        }
        mutex_unlock(&fs_info->ro_block_group_mutex);
@@ -9502,10 +9329,9 @@ out:
        return ret;
 }
 
-int btrfs_force_chunk_alloc(struct btrfs_trans_handle *trans,
-                           struct btrfs_fs_info *fs_info, u64 type)
+int btrfs_force_chunk_alloc(struct btrfs_trans_handle *trans, u64 type)
 {
-       u64 alloc_flags = get_alloc_profile(fs_info, type);
+       u64 alloc_flags = get_alloc_profile(trans->fs_info, type);
 
        return do_chunk_alloc(trans, alloc_flags, CHUNK_ALLOC_FORCE);
 }
@@ -9860,7 +9686,7 @@ int btrfs_free_block_groups(struct btrfs_fs_info *info)
                 */
                if (block_group->cached == BTRFS_CACHE_NO ||
                    block_group->cached == BTRFS_CACHE_ERROR)
-                       free_excluded_extents(info, block_group);
+                       free_excluded_extents(block_group);
 
                btrfs_remove_free_space_cache(block_group);
                ASSERT(block_group->cached != BTRFS_CACHE_STARTED);
@@ -10102,13 +9928,13 @@ int btrfs_read_block_groups(struct btrfs_fs_info *info)
                 * info has super bytes accounted for, otherwise we'll think
                 * we have more space than we actually do.
                 */
-               ret = exclude_super_stripes(info, cache);
+               ret = exclude_super_stripes(cache);
                if (ret) {
                        /*
                         * We may have excluded something, so call this just in
                         * case.
                         */
-                       free_excluded_extents(info, cache);
+                       free_excluded_extents(cache);
                        btrfs_put_block_group(cache);
                        goto error;
                }
@@ -10123,14 +9949,14 @@ int btrfs_read_block_groups(struct btrfs_fs_info *info)
                if (found_key.offset == btrfs_block_group_used(&cache->item)) {
                        cache->last_byte_to_unpin = (u64)-1;
                        cache->cached = BTRFS_CACHE_FINISHED;
-                       free_excluded_extents(info, cache);
+                       free_excluded_extents(cache);
                } else if (btrfs_block_group_used(&cache->item) == 0) {
                        cache->last_byte_to_unpin = (u64)-1;
                        cache->cached = BTRFS_CACHE_FINISHED;
                        add_new_free_space(cache, found_key.objectid,
                                           found_key.objectid +
                                           found_key.offset);
-                       free_excluded_extents(info, cache);
+                       free_excluded_extents(cache);
                }
 
                ret = btrfs_add_block_group_cache(info, cache);
@@ -10253,20 +10079,20 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans, u64 bytes_used,
        cache->last_byte_to_unpin = (u64)-1;
        cache->cached = BTRFS_CACHE_FINISHED;
        cache->needs_free_space = 1;
-       ret = exclude_super_stripes(fs_info, cache);
+       ret = exclude_super_stripes(cache);
        if (ret) {
                /*
                 * We may have excluded something, so call this just in
                 * case.
                 */
-               free_excluded_extents(fs_info, cache);
+               free_excluded_extents(cache);
                btrfs_put_block_group(cache);
                return ret;
        }
 
        add_new_free_space(cache, chunk_offset, chunk_offset + size);
 
-       free_excluded_extents(fs_info, cache);
+       free_excluded_extents(cache);
 
 #ifdef CONFIG_BTRFS_DEBUG
        if (btrfs_should_fragment_free_space(cache)) {
@@ -10350,7 +10176,7 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans,
         * Free the reserved super bytes from this block group before
         * remove it.
         */
-       free_excluded_extents(fs_info, block_group);
+       free_excluded_extents(block_group);
        btrfs_free_ref_tree_range(fs_info, block_group->key.objectid,
                                  block_group->key.offset);
 
@@ -10700,7 +10526,7 @@ void btrfs_delete_unused_bgs(struct btrfs_fs_info *fs_info)
                /* Don't want to race with allocators so take the groups_sem */
                down_write(&space_info->groups_sem);
                spin_lock(&block_group->lock);
-               if (block_group->reserved ||
+               if (block_group->reserved || block_group->pinned ||
                    btrfs_block_group_used(&block_group->item) ||
                    block_group->ro ||
                    list_is_singular(&block_group->list)) {