* tree until you end up with a lock on the root.  A locked buffer
  * is returned, with a reference held.
  */
-static struct extent_buffer *btrfs_read_lock_root_node(struct btrfs_root *root)
+struct extent_buffer *btrfs_read_lock_root_node(struct btrfs_root *root)
 {
        struct extent_buffer *eb;
 
 
                           struct extent_buffer *buf,
                           u64 parent, int last_ref);
 int btrfs_alloc_reserved_file_extent(struct btrfs_trans_handle *trans,
-                                    u64 root_objectid, u64 owner,
+                                    struct btrfs_root *root, u64 owner,
                                     u64 offset, u64 ram_bytes,
                                     struct btrfs_key *ins);
 int btrfs_alloc_logged_file_extent(struct btrfs_trans_handle *trans,
                                u64 bytenr, u64 num_bytes, u64 flags,
                                int level, int is_data);
 int btrfs_free_extent(struct btrfs_trans_handle *trans,
-                     struct btrfs_fs_info *fs_info,
+                     struct btrfs_root *root,
                      u64 bytenr, u64 num_bytes, u64 parent, u64 root_objectid,
                      u64 owner, u64 offset);
 
 int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans,
                               struct btrfs_fs_info *fs_info);
 int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
-                        struct btrfs_fs_info *fs_info,
+                        struct btrfs_root *root,
                         u64 bytenr, u64 num_bytes, u64 parent,
                         u64 root_objectid, u64 owner, u64 offset);
 
                             const struct btrfs_key *new_key);
 struct extent_buffer *btrfs_root_node(struct btrfs_root *root);
 struct extent_buffer *btrfs_lock_root_node(struct btrfs_root *root);
+struct extent_buffer *btrfs_read_lock_root_node(struct btrfs_root *root);
 int btrfs_find_next_key(struct btrfs_root *root, struct btrfs_path *path,
                        struct btrfs_key *key, int lowest_level,
                        u64 min_trans);
 
 
 /* Can return -ENOMEM */
 int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
-                        struct btrfs_fs_info *fs_info,
+                        struct btrfs_root *root,
                         u64 bytenr, u64 num_bytes, u64 parent,
                         u64 root_objectid, u64 owner, u64 offset)
 {
+       struct btrfs_fs_info *fs_info = root->fs_info;
        int old_ref_mod, new_ref_mod;
        int ret;
 
        int level;
        int ret = 0;
        int (*process_func)(struct btrfs_trans_handle *,
-                           struct btrfs_fs_info *,
+                           struct btrfs_root *,
                            u64, u64, u64, u64, u64, u64);
 
 
 
                        num_bytes = btrfs_file_extent_disk_num_bytes(buf, fi);
                        key.offset -= btrfs_file_extent_offset(buf, fi);
-                       ret = process_func(trans, fs_info, bytenr, num_bytes,
+                       ret = process_func(trans, root, bytenr, num_bytes,
                                           parent, ref_root, key.objectid,
                                           key.offset);
                        if (ret)
                } else {
                        bytenr = btrfs_node_blockptr(buf, i);
                        num_bytes = fs_info->nodesize;
-                       ret = process_func(trans, fs_info, bytenr, num_bytes,
+                       ret = process_func(trans, root, bytenr, num_bytes,
                                           parent, ref_root, level - 1, 0);
                        if (ret)
                                goto fail;
 
 /* Can return -ENOMEM */
 int btrfs_free_extent(struct btrfs_trans_handle *trans,
-                     struct btrfs_fs_info *fs_info,
+                     struct btrfs_root *root,
                      u64 bytenr, u64 num_bytes, u64 parent, u64 root_objectid,
                      u64 owner, u64 offset)
 {
+       struct btrfs_fs_info *fs_info = root->fs_info;
        int old_ref_mod, new_ref_mod;
        int ret;
 
        if (btrfs_is_testing(fs_info))
                return 0;
 
-
        /*
         * tree log blocks never actually go into the extent allocation
         * tree, just update pinning info and exit early.
 }
 
 int btrfs_alloc_reserved_file_extent(struct btrfs_trans_handle *trans,
-                                    u64 root_objectid, u64 owner,
+                                    struct btrfs_root *root, u64 owner,
                                     u64 offset, u64 ram_bytes,
                                     struct btrfs_key *ins)
 {
-       struct btrfs_fs_info *fs_info = trans->fs_info;
+       struct btrfs_fs_info *fs_info = root->fs_info;
        int ret;
 
-       BUG_ON(root_objectid == BTRFS_TREE_LOG_OBJECTID);
+       BUG_ON(root->root_key.objectid == BTRFS_TREE_LOG_OBJECTID);
 
        ret = btrfs_add_delayed_data_ref(fs_info, trans, ins->objectid,
-                                        ins->offset, 0, root_objectid, owner,
+                                        ins->offset, 0,
+                                        root->root_key.objectid, owner,
                                         offset, ram_bytes,
                                         BTRFS_ADD_DELAYED_EXTENT, NULL, NULL);
        return ret;
                                             ret);
                        }
                }
-               ret = btrfs_free_extent(trans, fs_info, bytenr, blocksize,
+               ret = btrfs_free_extent(trans, root, bytenr, blocksize,
                                        parent, root->root_key.objectid,
                                        level - 1, 0);
                if (ret)
 
                        btrfs_mark_buffer_dirty(leaf);
 
                        if (update_refs && disk_bytenr > 0) {
-                               ret = btrfs_inc_extent_ref(trans, fs_info,
+                               ret = btrfs_inc_extent_ref(trans, root,
                                                disk_bytenr, num_bytes, 0,
                                                root->root_key.objectid,
                                                new_key.objectid,
                                extent_end = ALIGN(extent_end,
                                                   fs_info->sectorsize);
                        } else if (update_refs && disk_bytenr > 0) {
-                               ret = btrfs_free_extent(trans, fs_info,
+                               ret = btrfs_free_extent(trans, root,
                                                disk_bytenr, num_bytes, 0,
                                                root->root_key.objectid,
                                                key.objectid, key.offset -
                                                extent_end - split);
                btrfs_mark_buffer_dirty(leaf);
 
-               ret = btrfs_inc_extent_ref(trans, fs_info, bytenr, num_bytes,
+               ret = btrfs_inc_extent_ref(trans, root, bytenr, num_bytes,
                                           0, root->root_key.objectid,
                                           ino, orig_offset);
                if (ret) {
                extent_end = other_end;
                del_slot = path->slots[0] + 1;
                del_nr++;
-               ret = btrfs_free_extent(trans, fs_info, bytenr, num_bytes,
+               ret = btrfs_free_extent(trans, root, bytenr, num_bytes,
                                        0, root->root_key.objectid,
                                        ino, orig_offset);
                if (ret) {
                key.offset = other_start;
                del_slot = path->slots[0];
                del_nr++;
-               ret = btrfs_free_extent(trans, fs_info, bytenr, num_bytes,
+               ret = btrfs_free_extent(trans, root, bytenr, num_bytes,
                                        0, root->root_key.objectid,
                                        ino, orig_offset);
                if (ret) {
 
        if (ret < 0)
                goto out;
        qg_released = ret;
-       ret = btrfs_alloc_reserved_file_extent(trans, root->root_key.objectid,
-                       btrfs_ino(BTRFS_I(inode)), file_pos, qg_released, &ins);
+       ret = btrfs_alloc_reserved_file_extent(trans, root,
+                                              btrfs_ino(BTRFS_I(inode)),
+                                              file_pos, qg_released, &ins);
 out:
        btrfs_free_path(path);
 
        inode_add_bytes(inode, len);
        btrfs_release_path(path);
 
-       ret = btrfs_inc_extent_ref(trans, fs_info, new->bytenr,
+       ret = btrfs_inc_extent_ref(trans, root, new->bytenr,
                        new->disk_len, 0,
                        backref->root_id, backref->inum,
                        new->file_pos); /* start - extent_offset */
                     root == fs_info->tree_root)) {
                        btrfs_set_path_blocking(path);
                        bytes_deleted += extent_num_bytes;
-                       ret = btrfs_free_extent(trans, fs_info, extent_start,
+                       ret = btrfs_free_extent(trans, root, extent_start,
                                                extent_num_bytes, 0,
                                                btrfs_header_owner(leaf),
                                                ino, extent_offset);
 
                                if (disko) {
                                        inode_add_bytes(inode, datal);
                                        ret = btrfs_inc_extent_ref(trans,
-                                                       fs_info,
+                                                       root,
                                                        disko, diskl, 0,
                                                        root->root_key.objectid,
                                                        btrfs_ino(BTRFS_I(inode)),
 
                dirty = 1;
 
                key.offset -= btrfs_file_extent_offset(leaf, fi);
-               ret = btrfs_inc_extent_ref(trans, fs_info, new_bytenr,
+               ret = btrfs_inc_extent_ref(trans, root, new_bytenr,
                                           num_bytes, parent,
                                           btrfs_header_owner(leaf),
                                           key.objectid, key.offset);
                        break;
                }
 
-               ret = btrfs_free_extent(trans, fs_info, bytenr, num_bytes,
+               ret = btrfs_free_extent(trans, root, bytenr, num_bytes,
                                        parent, btrfs_header_owner(leaf),
                                        key.objectid, key.offset);
                if (ret) {
                                              path->slots[level], old_ptr_gen);
                btrfs_mark_buffer_dirty(path->nodes[level]);
 
-               ret = btrfs_inc_extent_ref(trans, fs_info, old_bytenr,
+               ret = btrfs_inc_extent_ref(trans, src, old_bytenr,
                                        blocksize, path->nodes[level]->start,
                                        src->root_key.objectid, level - 1, 0);
                BUG_ON(ret);
-               ret = btrfs_inc_extent_ref(trans, fs_info, new_bytenr,
+               ret = btrfs_inc_extent_ref(trans, dest, new_bytenr,
                                        blocksize, 0, dest->root_key.objectid,
                                        level - 1, 0);
                BUG_ON(ret);
 
-               ret = btrfs_free_extent(trans, fs_info, new_bytenr, blocksize,
+               ret = btrfs_free_extent(trans, src, new_bytenr, blocksize,
                                        path->nodes[level]->start,
                                        src->root_key.objectid, level - 1, 0);
                BUG_ON(ret);
 
-               ret = btrfs_free_extent(trans, fs_info, old_bytenr, blocksize,
+               ret = btrfs_free_extent(trans, dest, old_bytenr, blocksize,
                                        0, dest->root_key.objectid, level - 1,
                                        0);
                BUG_ON(ret);
                                                      trans->transid);
                        btrfs_mark_buffer_dirty(upper->eb);
 
-                       ret = btrfs_inc_extent_ref(trans, root->fs_info,
+                       ret = btrfs_inc_extent_ref(trans, root,
                                                node->eb->start, blocksize,
                                                upper->eb->start,
                                                btrfs_header_owner(upper->eb),
 
                        ret = btrfs_lookup_data_extent(fs_info, ins.objectid,
                                                ins.offset);
                        if (ret == 0) {
-                               ret = btrfs_inc_extent_ref(trans, fs_info,
+                               ret = btrfs_inc_extent_ref(trans, root,
                                                ins.objectid, ins.offset,
                                                0, root->root_key.objectid,
                                                key->objectid, offset);