btrfs-progs: test for restoring multiple devices fs into a single device
[platform/upstream/btrfs-progs.git] / extent-tree.c
index 5ca53fa..b12ee29 100644 (file)
@@ -80,7 +80,7 @@ static int remove_sb_from_cache(struct btrfs_root *root,
                BUG_ON(ret);
                while (nr--) {
                        clear_extent_dirty(free_space_cache, logical[nr],
-                               logical[nr] + stripe_len - 1, GFP_NOFS);
+                               logical[nr] + stripe_len - 1);
                }
                kfree(logical);
        }
@@ -149,8 +149,7 @@ static int cache_block_group(struct btrfs_root *root,
                        if (key.objectid > last) {
                                hole_size = key.objectid - last;
                                set_extent_dirty(free_space_cache, last,
-                                                last + hole_size - 1,
-                                                GFP_NOFS);
+                                                last + hole_size - 1);
                        }
                        if (key.type == BTRFS_METADATA_ITEM_KEY)
                                last = key.objectid + root->nodesize;
@@ -165,8 +164,7 @@ next:
            block_group->key.offset > last) {
                hole_size = block_group->key.objectid +
                        block_group->key.offset - last;
-               set_extent_dirty(free_space_cache, last,
-                                last + hole_size - 1, GFP_NOFS);
+               set_extent_dirty(free_space_cache, last, last + hole_size - 1);
        }
        remove_sb_from_cache(root, block_group);
        block_group->cached = 1;
@@ -574,7 +572,7 @@ static int convert_extent_item_v0(struct btrfs_trans_handle *trans,
                return ret;
        BUG_ON(ret);
 
-       ret = btrfs_extend_item(trans, root, path, new_size);
+       ret = btrfs_extend_item(root, path, new_size);
        BUG_ON(ret);
 
        leaf = path->nodes[0];
@@ -598,7 +596,7 @@ static int convert_extent_item_v0(struct btrfs_trans_handle *trans,
 }
 #endif
 
-static u64 hash_extent_data_ref(u64 root_objectid, u64 owner, u64 offset)
+u64 hash_extent_data_ref(u64 root_objectid, u64 owner, u64 offset)
 {
        u32 high_crc = ~(u32)0;
        u32 low_crc = ~(u32)0;
@@ -857,8 +855,7 @@ static noinline int remove_extent_data_ref(struct btrfs_trans_handle *trans,
        return ret;
 }
 
-static noinline u32 extent_data_ref_count(struct btrfs_root *root,
-                                         struct btrfs_path *path,
+static noinline u32 extent_data_ref_count(struct btrfs_path *path,
                                          struct btrfs_extent_inline_ref *iref)
 {
        struct btrfs_key key;
@@ -995,8 +992,7 @@ static int lookup_inline_extent_backref(struct btrfs_trans_handle *trans,
        int ret;
        int err = 0;
        int skinny_metadata =
-               btrfs_fs_incompat(root->fs_info,
-                                 BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA);
+               btrfs_fs_incompat(root->fs_info, SKINNY_METADATA);
 
        key.objectid = bytenr;
        key.type = BTRFS_EXTENT_ITEM_KEY;
@@ -1165,8 +1161,7 @@ out:
        return err;
 }
 
-static int setup_inline_extent_backref(struct btrfs_trans_handle *trans,
-                               struct btrfs_root *root,
+static int setup_inline_extent_backref(struct btrfs_root *root,
                                struct btrfs_path *path,
                                struct btrfs_extent_inline_ref *iref,
                                u64 parent, u64 root_objectid,
@@ -1189,7 +1184,7 @@ static int setup_inline_extent_backref(struct btrfs_trans_handle *trans,
        type = extent_ref_type(parent, owner);
        size = btrfs_extent_inline_ref_size(type);
 
-       ret = btrfs_extend_item(trans, root, path, size);
+       ret = btrfs_extend_item(root, path, size);
        BUG_ON(ret);
 
        ei = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_extent_item);
@@ -1309,7 +1304,7 @@ static int update_inline_extent_backref(struct btrfs_trans_handle *trans,
                        memmove_extent_buffer(leaf, ptr, ptr + size,
                                              end - ptr - size);
                item_size -= size;
-               ret = btrfs_truncate_item(trans, root, path, item_size, 1);
+               ret = btrfs_truncate_item(root, path, item_size, 1);
                BUG_ON(ret);
        }
        btrfs_mark_buffer_dirty(leaf);
@@ -1334,7 +1329,7 @@ static int insert_inline_extent_backref(struct btrfs_trans_handle *trans,
                ret = update_inline_extent_backref(trans, root, path, iref,
                                                   refs_to_add);
        } else if (ret == -ENOENT) {
-               ret = setup_inline_extent_backref(trans, root, path, iref,
+               ret = setup_inline_extent_backref(root, path, iref,
                                                  parent, root_objectid,
                                                  owner, offset, refs_to_add);
        }
@@ -1456,8 +1451,7 @@ int btrfs_lookup_extent_info(struct btrfs_trans_handle *trans,
        u64 extent_flags;
 
        if (metadata &&
-           !btrfs_fs_incompat(root->fs_info,
-                              BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA)) {
+           !btrfs_fs_incompat(root->fs_info, SKINNY_METADATA)) {
                offset = root->nodesize;
                metadata = 0;
        }
@@ -1552,8 +1546,7 @@ int btrfs_set_block_flags(struct btrfs_trans_handle *trans,
        struct btrfs_extent_item *item;
        u32 item_size;
        int skinny_metadata =
-               btrfs_fs_incompat(root->fs_info,
-                                 BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA);
+               btrfs_fs_incompat(root->fs_info, SKINNY_METADATA);
 
        path = btrfs_alloc_path();
        if (!path)
@@ -1664,7 +1657,7 @@ static int __btrfs_mod_ref(struct btrfs_trans_handle *trans,
                cond_resched();
                if (level == 0) {
                        btrfs_item_key_to_cpu(buf, &key, i);
-                       if (btrfs_key_type(&key) != BTRFS_EXTENT_DATA_KEY)
+                       if (key.type != BTRFS_EXTENT_DATA_KEY)
                                continue;
                        fi = btrfs_item_ptr(buf, i,
                                            struct btrfs_file_extent_item);
@@ -1777,7 +1770,7 @@ int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans,
                BUG_ON(ret);
 
                clear_extent_bits(block_group_cache, start, end,
-                                 BLOCK_GROUP_DIRTY, GFP_NOFS);
+                                 BLOCK_GROUP_DIRTY);
 
                cache = (struct btrfs_block_group_cache *)(unsigned long)ptr;
                ret = write_one_cache_group(trans, root, path, cache);
@@ -1968,7 +1961,7 @@ static int update_block_group(struct btrfs_trans_handle *trans,
                start = cache->key.objectid;
                end = start + cache->key.offset - 1;
                set_extent_bits(&info->block_group_cache, start, end,
-                               BLOCK_GROUP_DIRTY, GFP_NOFS);
+                               BLOCK_GROUP_DIRTY);
 
                old_val = btrfs_block_group_used(&cache->item);
                num_bytes = min(total, cache->key.offset - byte_in_group);
@@ -1981,8 +1974,7 @@ static int update_block_group(struct btrfs_trans_handle *trans,
                        cache->space_info->bytes_used -= num_bytes;
                        if (mark_free) {
                                set_extent_dirty(&info->free_space_cache,
-                                                bytenr, bytenr + num_bytes - 1,
-                                                GFP_NOFS);
+                                               bytenr, bytenr + num_bytes - 1);
                        }
                }
                btrfs_set_block_group_used(&cache->item, old_val);
@@ -2001,10 +1993,10 @@ static int update_pinned_extents(struct btrfs_root *root,
 
        if (pin) {
                set_extent_dirty(&fs_info->pinned_extents,
-                               bytenr, bytenr + num - 1, GFP_NOFS);
+                               bytenr, bytenr + num - 1);
        } else {
                clear_extent_dirty(&fs_info->pinned_extents,
-                               bytenr, bytenr + num - 1, GFP_NOFS);
+                               bytenr, bytenr + num - 1);
        }
        while (num > 0) {
                cache = btrfs_lookup_block_group(fs_info, bytenr);
@@ -2047,8 +2039,8 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans,
                if (ret)
                        break;
                update_pinned_extents(root, start, end + 1 - start, 0);
-               clear_extent_dirty(unpin, start, end, GFP_NOFS);
-               set_extent_dirty(free_space_cache, start, end, GFP_NOFS);
+               clear_extent_dirty(unpin, start, end);
+               set_extent_dirty(free_space_cache, start, end);
        }
        return 0;
 }
@@ -2079,8 +2071,7 @@ static int finish_current_insert(struct btrfs_trans_handle *trans,
        struct btrfs_key key;
        int ret;
        int skinny_metadata =
-               btrfs_fs_incompat(extent_root->fs_info,
-                                 BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA);
+               btrfs_fs_incompat(extent_root->fs_info, SKINNY_METADATA);
 
        while(1) {
                ret = find_first_extent_bit(&info->extent_ins, 0, &start,
@@ -2112,8 +2103,7 @@ static int finish_current_insert(struct btrfs_trans_handle *trans,
                        BUG_ON(1);
                }
 
-               clear_extent_bits(&info->extent_ins, start, end, EXTENT_LOCKED,
-                                 GFP_NOFS);
+               clear_extent_bits(&info->extent_ins, start, end, EXTENT_LOCKED);
                kfree(extent_op);
        }
        return 0;
@@ -2193,8 +2183,7 @@ static int __free_extent(struct btrfs_trans_handle *trans,
        u32 item_size;
        u64 refs;
        int skinny_metadata =
-               btrfs_fs_incompat(extent_root->fs_info,
-                                 BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA);
+               btrfs_fs_incompat(extent_root->fs_info, SKINNY_METADATA);
 
        if (root->fs_info->free_extent_hook) {
                root->fs_info->free_extent_hook(trans, root, bytenr, num_bytes,
@@ -2371,7 +2360,7 @@ static int __free_extent(struct btrfs_trans_handle *trans,
 
                if (found_extent) {
                        BUG_ON(is_data && refs_to_drop !=
-                              extent_data_ref_count(root, path, iref));
+                              extent_data_ref_count(path, iref));
                        if (iref) {
                                BUG_ON(path->slots[0] != extent_slot);
                        } else {
@@ -2436,8 +2425,7 @@ static int del_pending_extents(struct btrfs_trans_handle *trans, struct
                BUG_ON(ret);
                extent_op = (struct pending_extent_op *)(unsigned long)priv;
 
-               clear_extent_bits(pending_del, start, end, EXTENT_LOCKED,
-                                 GFP_NOFS);
+               clear_extent_bits(pending_del, start, end, EXTENT_LOCKED);
 
                if (!test_range_bit(extent_ins, start, end,
                                    EXTENT_LOCKED, 0)) {
@@ -2454,7 +2442,7 @@ static int del_pending_extents(struct btrfs_trans_handle *trans, struct
                                                        (unsigned long)priv;
 
                        clear_extent_bits(extent_ins, start, end,
-                                         EXTENT_LOCKED, GFP_NOFS);
+                                         EXTENT_LOCKED);
 
                        if (extent_op->type == PENDING_BACKREF_UPDATE)
                                BUG_ON(1);
@@ -2467,6 +2455,17 @@ static int del_pending_extents(struct btrfs_trans_handle *trans, struct
        return err;
 }
 
+
+int btrfs_free_tree_block(struct btrfs_trans_handle *trans,
+                         struct btrfs_root *root,
+                         struct extent_buffer *buf,
+                         u64 parent, int last_ref)
+{
+       return btrfs_free_extent(trans, root, buf->start, buf->len, parent,
+                                root->root_key.objectid,
+                                btrfs_header_level(buf), 0);
+}
+
 /*
  * remove an extent from the root, returns 0 on success
  */
@@ -2494,7 +2493,7 @@ int btrfs_free_extent(struct btrfs_trans_handle *trans,
 
                set_extent_bits(&root->fs_info->pending_del,
                                bytenr, bytenr + num_bytes - 1,
-                               EXTENT_LOCKED, GFP_NOFS);
+                               EXTENT_LOCKED);
                set_state_private(&root->fs_info->pending_del,
                                  bytenr, (unsigned long)extent_op);
                return 0;
@@ -2538,7 +2537,7 @@ static int noinline find_free_extent(struct btrfs_trans_handle *trans,
        int wrapped = 0;
 
        WARN_ON(num_bytes < root->sectorsize);
-       btrfs_set_key_type(ins, BTRFS_EXTENT_ITEM_KEY);
+       ins->type = BTRFS_EXTENT_ITEM_KEY;
 
        search_start = stripe_align(root, search_start);
 
@@ -2606,11 +2605,20 @@ check_failed:
        }
 
        if (!(data & BTRFS_BLOCK_GROUP_DATA)) {
-               if (check_crossing_stripes(ins->objectid, num_bytes)) {
-                       search_start = round_down(ins->objectid + num_bytes,
-                                                 BTRFS_STRIPE_LEN);
+               if (check_crossing_stripes(info, ins->objectid, num_bytes)) {
+                       struct btrfs_block_group_cache *bg_cache;
+                       u64 bg_offset;
+
+                       bg_cache = btrfs_lookup_block_group(info, ins->objectid);
+                       if (!bg_cache)
+                               goto no_bg_cache;
+                       bg_offset = ins->objectid - bg_cache->key.objectid;
+
+                       search_start = round_up(bg_offset + num_bytes,
+                                               BTRFS_STRIPE_LEN) + bg_offset;
                        goto new_group;
                }
+no_bg_cache:
                block_group = btrfs_lookup_block_group(info, ins->objectid);
                if (block_group)
                        trans->block_group = block_group;
@@ -2676,7 +2684,7 @@ int btrfs_reserve_extent(struct btrfs_trans_handle *trans,
                        BUG_ON(ret);
                }
                ret = do_chunk_alloc(trans, root->fs_info->extent_root,
-                                    num_bytes + 2 * 1024 * 1024, data);
+                                    num_bytes + SZ_2M, data);
                BUG_ON(ret);
        }
 
@@ -2687,8 +2695,7 @@ int btrfs_reserve_extent(struct btrfs_trans_handle *trans,
                               trans->alloc_exclude_nr, data);
        BUG_ON(ret);
        clear_extent_dirty(&root->fs_info->free_space_cache,
-                          ins->objectid, ins->objectid + ins->offset - 1,
-                          GFP_NOFS);
+                          ins->objectid, ins->objectid + ins->offset - 1);
        return ret;
 }
 
@@ -2706,15 +2713,14 @@ static int alloc_reserved_tree_block(struct btrfs_trans_handle *trans,
        struct btrfs_path *path;
        struct extent_buffer *leaf;
        u32 size = sizeof(*extent_item) + sizeof(*iref);
-       int skinny_metadata =
-               btrfs_fs_incompat(fs_info,
-                                 BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA);
+       int skinny_metadata = btrfs_fs_incompat(fs_info, SKINNY_METADATA);
 
        if (!skinny_metadata)
                size += sizeof(*block_info);
 
        path = btrfs_alloc_path();
-       BUG_ON(!path);
+       if (!path)
+               return -ENOMEM;
 
        ret = btrfs_insert_empty_item(trans, fs_info->extent_root, path,
                                      ins, size);
@@ -2775,12 +2781,11 @@ static int alloc_tree_block(struct btrfs_trans_handle *trans,
 
                set_extent_bits(&root->fs_info->extent_ins, ins->objectid,
                                ins->objectid + ins->offset - 1,
-                               EXTENT_LOCKED, GFP_NOFS);
+                               EXTENT_LOCKED);
                set_state_private(&root->fs_info->extent_ins,
                                  ins->objectid, (unsigned long)extent_op);
        } else {
-               if (btrfs_fs_incompat(root->fs_info,
-                               BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA)) {
+               if (btrfs_fs_incompat(root->fs_info, SKINNY_METADATA)) {
                        ins->offset = level;
                        ins->type = BTRFS_METADATA_ITEM_KEY;
                }
@@ -2895,8 +2900,8 @@ static void noinline reada_walk_down(struct btrfs_root *root,
 
        for (i = slot; i < nritems && skipped < 32; i++) {
                bytenr = btrfs_node_blockptr(node, i);
-               if (last && ((bytenr > last && bytenr - last > 32 * 1024) ||
-                            (last > bytenr && last - bytenr > 32 * 1024))) {
+               if (last && ((bytenr > last && bytenr - last > SZ_32K) ||
+                            (last > bytenr && last - bytenr > SZ_32K))) {
                        skipped++;
                        continue;
                }
@@ -3110,15 +3115,14 @@ int btrfs_free_block_groups(struct btrfs_fs_info *info)
                        kfree(cache);
                }
                clear_extent_bits(&info->block_group_cache, start,
-                                 end, (unsigned int)-1, GFP_NOFS);
+                                 end, (unsigned int)-1);
        }
        while(1) {
                ret = find_first_extent_bit(&info->free_space_cache, 0,
                                            &start, &end, EXTENT_DIRTY);
                if (ret)
                        break;
-               clear_extent_dirty(&info->free_space_cache, start,
-                                  end, GFP_NOFS);
+               clear_extent_dirty(&info->free_space_cache, start, end);
        }
 
        while (!list_empty(&info->space_info)) {
@@ -3230,7 +3234,7 @@ int btrfs_read_block_groups(struct btrfs_root *root)
        root = info->extent_root;
        key.objectid = 0;
        key.offset = 0;
-       btrfs_set_key_type(&key, BTRFS_BLOCK_GROUP_ITEM_KEY);
+       key.type = BTRFS_BLOCK_GROUP_ITEM_KEY;
        path = btrfs_alloc_path();
        if (!path)
                return -ENOMEM;
@@ -3246,6 +3250,7 @@ int btrfs_read_block_groups(struct btrfs_root *root)
                }
                leaf = path->nodes[0];
                btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
+
                cache = kzalloc(sizeof(*cache), GFP_NOFS);
                if (!cache) {
                        ret = -ENOMEM;
@@ -3259,7 +3264,20 @@ int btrfs_read_block_groups(struct btrfs_root *root)
                cache->cached = 0;
                cache->pinned = 0;
                key.objectid = found_key.objectid + found_key.offset;
+               if (found_key.offset == 0)
+                       key.objectid++;
                btrfs_release_path(path);
+
+               /*
+                * Skip 0 sized block group, don't insert them into block
+                * group cache tree, as its length is 0, it won't get
+                * freed at close_ctree() time.
+                */
+               if (found_key.offset == 0) {
+                       free(cache);
+                       continue;
+               }
+
                cache->flags = btrfs_block_group_flags(&cache->item);
                bit = 0;
                if (cache->flags & BTRFS_BLOCK_GROUP_DATA) {
@@ -3284,7 +3302,7 @@ int btrfs_read_block_groups(struct btrfs_root *root)
                /* use EXTENT_LOCKED to prevent merging */
                set_extent_bits(block_group_cache, found_key.objectid,
                                found_key.objectid + found_key.offset - 1,
-                               bit | EXTENT_LOCKED, GFP_NOFS);
+                               bit | EXTENT_LOCKED);
                set_state_private(block_group_cache, found_key.objectid,
                                  (unsigned long)cache);
        }
@@ -3310,7 +3328,7 @@ btrfs_add_block_group(struct btrfs_fs_info *fs_info, u64 bytes_used, u64 type,
        cache->key.objectid = chunk_offset;
        cache->key.offset = size;
 
-       btrfs_set_key_type(&cache->key, BTRFS_BLOCK_GROUP_ITEM_KEY);
+       cache->key.type = BTRFS_BLOCK_GROUP_ITEM_KEY;
        btrfs_set_block_group_used(&cache->item, bytes_used);
        btrfs_set_block_group_chunk_objectid(&cache->item, chunk_objectid);
        cache->flags = type;
@@ -3324,7 +3342,7 @@ btrfs_add_block_group(struct btrfs_fs_info *fs_info, u64 bytes_used, u64 type,
        bit = block_group_state_bits(type);
        ret = set_extent_bits(block_group_cache, chunk_offset,
                              chunk_offset + size - 1,
-                             bit | EXTENT_LOCKED, GFP_NOFS);
+                             bit | EXTENT_LOCKED);
        BUG_ON(ret);
 
        ret = set_state_private(block_group_cache, chunk_offset,
@@ -3398,19 +3416,18 @@ int btrfs_make_block_groups(struct btrfs_trans_handle *trans,
                        group_type = BTRFS_BLOCK_GROUP_SYSTEM;
                        group_size /= 4;
                        group_size &= ~(group_align - 1);
-                       group_size = max_t(u64, group_size, 8 * 1024 * 1024);
-                       group_size = min_t(u64, group_size, 32 * 1024 * 1024);
+                       group_size = max_t(u64, group_size, SZ_8M);
+                       group_size = min_t(u64, group_size, SZ_32M);
                } else {
                        group_size &= ~(group_align - 1);
                        if (total_data >= total_metadata * 2) {
                                group_type = BTRFS_BLOCK_GROUP_METADATA;
-                               group_size = min_t(u64, group_size,
-                                                  1ULL * 1024 * 1024 * 1024);
+                               group_size = min_t(u64, group_size, SZ_1G);
                                total_metadata += group_size;
                        } else {
                                group_type = BTRFS_BLOCK_GROUP_DATA;
                                group_size = min_t(u64, group_size,
-                                                  5ULL * 1024 * 1024 * 1024);
+                                                  5ULL * SZ_1G);
                                total_data += group_size;
                        }
                        if ((total_bytes - cur_start) * 4 < group_size * 5)
@@ -3422,7 +3439,7 @@ int btrfs_make_block_groups(struct btrfs_trans_handle *trans,
 
                cache->key.objectid = cur_start;
                cache->key.offset = group_size;
-               btrfs_set_key_type(&cache->key, BTRFS_BLOCK_GROUP_ITEM_KEY);
+               cache->key.type = BTRFS_BLOCK_GROUP_ITEM_KEY;
 
                btrfs_set_block_group_used(&cache->item, 0);
                btrfs_set_block_group_chunk_objectid(&cache->item,
@@ -3438,7 +3455,7 @@ int btrfs_make_block_groups(struct btrfs_trans_handle *trans,
 
                set_extent_bits(block_group_cache, cur_start,
                                cur_start + group_size - 1,
-                               bit | EXTENT_LOCKED, GFP_NOFS);
+                               bit | EXTENT_LOCKED);
                set_state_private(block_group_cache, cur_start,
                                  (unsigned long)cache);
                cur_start += group_size;
@@ -3627,7 +3644,7 @@ out:
 
 static int free_chunk_item(struct btrfs_trans_handle *trans,
                           struct btrfs_fs_info *fs_info,
-                          u64 bytenr, u64 len)
+                          u64 bytenr)
 {
        struct btrfs_path *path;
        struct btrfs_key key;
@@ -3714,7 +3731,7 @@ static int free_block_group_cache(struct btrfs_trans_handle *trans,
                kfree(cache->free_space_ctl);
        }
        clear_extent_bits(&fs_info->block_group_cache, bytenr, bytenr + len,
-                         (unsigned int)-1, GFP_NOFS);
+                         (unsigned int)-1);
        ret = free_space_info(fs_info, flags, len, 0, NULL);
        if (ret < 0)
                goto out;
@@ -3804,7 +3821,7 @@ int btrfs_free_block_group(struct btrfs_trans_handle *trans,
                btrfs_unpin_extent(fs_info, bytenr, len);
                goto out;
        }
-       ret = free_chunk_item(trans, fs_info, bytenr, len);
+       ret = free_chunk_item(trans, fs_info, bytenr);
        if (ret < 0) {
                fprintf(stderr,
                        "failed to free chunk for [%llu,%llu)\n",
@@ -3860,13 +3877,13 @@ int btrfs_fix_block_accounting(struct btrfs_trans_handle *trans,
                set_extent_bits(&root->fs_info->block_group_cache,
                                cache->key.objectid,
                                cache->key.objectid + cache->key.offset -1,
-                               BLOCK_GROUP_DIRTY, GFP_NOFS);
+                               BLOCK_GROUP_DIRTY);
        }
 
        btrfs_init_path(&path);
        key.offset = 0;
        key.objectid = 0;
-       btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY);
+       key.type = BTRFS_EXTENT_ITEM_KEY;
        ret = btrfs_search_slot(trans, root->fs_info->extent_root,
                                &key, &path, 0, 0);
        if (ret < 0)
@@ -3985,10 +4002,11 @@ static int __btrfs_record_file_extent(struct btrfs_trans_handle *trans,
        u64 extent_offset;
        u64 num_bytes = *ret_num_bytes;
 
-       num_bytes = min_t(u64, num_bytes, BTRFS_MAX_EXTENT_SIZE);
        /*
         * All supported file system should not use its 0 extent.
         * As it's for hole
+        *
+        * And hole extent has no size limit, no need to loop.
         */
        if (disk_bytenr == 0) {
                ret = btrfs_insert_file_extent(trans, root, objectid,
@@ -3996,6 +4014,7 @@ static int __btrfs_record_file_extent(struct btrfs_trans_handle *trans,
                                                num_bytes, num_bytes);
                return ret;
        }
+       num_bytes = min_t(u64, num_bytes, BTRFS_MAX_EXTENT_SIZE);
 
        path = btrfs_alloc_path();
        if (!path)
@@ -4056,7 +4075,7 @@ static int __btrfs_record_file_extent(struct btrfs_trans_handle *trans,
        btrfs_release_path(path);
        ins_key.objectid = objectid;
        ins_key.offset = file_pos;
-       btrfs_set_key_type(&ins_key, BTRFS_EXTENT_DATA_KEY);
+       ins_key.type = BTRFS_EXTENT_DATA_KEY;
        ret = btrfs_insert_empty_item(trans, root, path, &ins_key,
                                      sizeof(*fi));
        if (ret)
@@ -4128,7 +4147,7 @@ static int add_excluded_extent(struct btrfs_root *root,
 {
        u64 end = start + num_bytes - 1;
        set_extent_bits(&root->fs_info->pinned_extents,
-                       start, end, EXTENT_UPTODATE, GFP_NOFS);
+                       start, end, EXTENT_UPTODATE);
        return 0;
 }
 
@@ -4141,7 +4160,7 @@ void free_excluded_extents(struct btrfs_root *root,
        end = start + cache->key.offset - 1;
 
        clear_extent_bits(&root->fs_info->pinned_extents,
-                         start, end, EXTENT_UPTODATE, GFP_NOFS);
+                         start, end, EXTENT_UPTODATE);
 }
 
 int exclude_super_stripes(struct btrfs_root *root,