diff --git a/common/extent-tree-utils.c b/common/extent-tree-utils.c
index 9f7e543f3bd1..135798b98511 100644
--- a/common/extent-tree-utils.c
+++ b/common/extent-tree-utils.c
@@ -15,18 +15,13 @@
  */
 
 #include "kerncompat.h"
-#include <errno.h>
 #include <stddef.h>
 #include "kernel-shared/accessors.h"
 #include "kernel-shared/uapi/btrfs_tree.h"
 #include "kernel-shared/ctree.h"
 #include "kernel-shared/disk-io.h"
-#include "kernel-shared/file-item.h"
 #include "kernel-shared/transaction.h"
-#include "kernel-shared/free-space-tree.h"
-#include "common/internal.h"
 #include "common/extent-tree-utils.h"
-#include "common/messages.h"
 
 /*
  * Search in extent tree to found next meta/data extent. Caller needs to check
@@ -50,238 +45,3 @@ int btrfs_next_extent_item(struct btrfs_root *root, struct btrfs_path *path,
 		return 0;
 	}
 }
-
-static void __get_extent_size(struct btrfs_root *root, struct btrfs_path *path,
-			      u64 *start, u64 *len)
-{
-	struct btrfs_key key;
-
-	btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);
-	BUG_ON(!(key.type == BTRFS_EXTENT_ITEM_KEY ||
-		 key.type == BTRFS_METADATA_ITEM_KEY));
-	*start = key.objectid;
-	if (key.type == BTRFS_EXTENT_ITEM_KEY)
-		*len = key.offset;
-	else
-		*len = root->fs_info->nodesize;
-}
-
-/*
- * Find first overlap extent for range [bytenr, bytenr + len).
- *
- * Return 0 for found and point path to it.
- * Return >0 for not found.
- * Return <0 for err
- */
-static int btrfs_search_overlap_extent(struct btrfs_root *root,
-				       struct btrfs_path *path, u64 bytenr, u64 len)
-{
-	struct btrfs_key key;
-	u64 cur_start;
-	u64 cur_len;
-	int ret;
-
-	key.objectid = bytenr;
-	key.type = BTRFS_EXTENT_DATA_KEY;
-	key.offset = (u64)-1;
-
-	ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
-	if (ret < 0)
-		return ret;
-	if (ret == 0) {
-		error_msg(ERROR_MSG_UNEXPECTED, "EXTENT_DATA found at %llu", bytenr);
-		return -EUCLEAN;
-	}
-
-	ret = btrfs_previous_extent_item(root, path, 0);
-	if (ret < 0)
-		return ret;
-	/* No previous, check next extent. */
-	if (ret > 0)
-		goto next;
-	__get_extent_size(root, path, &cur_start, &cur_len);
-	/* Tail overlap. */
-	if (cur_start + cur_len > bytenr)
-		return 1;
-
-next:
-	ret = btrfs_next_extent_item(root, path, bytenr + len);
-	if (ret < 0)
-		return ret;
-	/* No next, prev already checked, no overlap. */
-	if (ret > 0)
-		return 0;
-	__get_extent_size(root, path, &cur_start, &cur_len);
-	/* Head overlap.*/
-	if (cur_start < bytenr + len)
-		return 1;
-	return 0;
-}
-
-static int __btrfs_record_file_extent(struct btrfs_trans_handle *trans,
-				      struct btrfs_root *root, u64 objectid,
-				      struct btrfs_inode_item *inode,
-				      u64 file_pos, u64 disk_bytenr,
-				      u64 *ret_num_bytes)
-{
-	int ret;
-	struct btrfs_fs_info *info = root->fs_info;
-	struct btrfs_root *extent_root = btrfs_extent_root(info, disk_bytenr);
-	struct extent_buffer *leaf;
-	struct btrfs_file_extent_item *fi;
-	struct btrfs_key ins_key;
-	struct btrfs_path *path;
-	struct btrfs_extent_item *ei;
-	u64 nbytes;
-	u64 extent_num_bytes;
-	u64 extent_bytenr;
-	u64 extent_offset;
-	u64 num_bytes = *ret_num_bytes;
-
-	/*
-	 * @objectid should be an inode number, thus it must not be smaller
-	 * than BTRFS_FIRST_FREE_OBJECTID.
-	 */
-	UASSERT(objectid >= BTRFS_FIRST_FREE_OBJECTID);
-
-	/*
-	 * 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,
-					       file_pos, disk_bytenr,
-					       num_bytes, num_bytes);
-		return ret;
-	}
-	num_bytes = min_t(u64, num_bytes, BTRFS_MAX_EXTENT_SIZE);
-
-	path = btrfs_alloc_path();
-	if (!path)
-		return -ENOMEM;
-
-	/* First to check extent overlap. */
-	ret = btrfs_search_overlap_extent(extent_root, path, disk_bytenr, num_bytes);
-	if (ret < 0)
-		goto fail;
-	if (ret > 0) {
-		/* Found overlap. */
-		u64 cur_start;
-		u64 cur_len;
-
-		__get_extent_size(extent_root, path, &cur_start, &cur_len);
-		/* For convert case, this extent should be a subset of existing one. */
-		if (disk_bytenr < cur_start) {
-			error_msg(ERROR_MSG_UNEXPECTED,
-				  "invalid range disk_bytenr < cur_start: %llu < %llu",
-				  disk_bytenr, cur_start);
-			ret = -EUCLEAN;
-			goto fail;
-		}
-
-		extent_bytenr = cur_start;
-		extent_num_bytes = cur_len;
-		extent_offset = disk_bytenr - extent_bytenr;
-	} else {
-		/* No overlap, create new extent. */
-		btrfs_release_path(path);
-		ins_key.objectid = disk_bytenr;
-		ins_key.type = BTRFS_EXTENT_ITEM_KEY;
-		ins_key.offset = num_bytes;
-
-		ret = btrfs_insert_empty_item(trans, extent_root, path,
-					      &ins_key, sizeof(*ei));
-		if (ret == 0) {
-			leaf = path->nodes[0];
-			ei = btrfs_item_ptr(leaf, path->slots[0],
-					    struct btrfs_extent_item);
-
-			btrfs_set_extent_refs(leaf, ei, 0);
-			btrfs_set_extent_generation(leaf, ei, trans->transid);
-			btrfs_set_extent_flags(leaf, ei,
-					       BTRFS_EXTENT_FLAG_DATA);
-			btrfs_mark_buffer_dirty(leaf);
-
-			ret = btrfs_update_block_group(trans, disk_bytenr,
-						       num_bytes, 1, 0);
-			if (ret)
-				goto fail;
-		} else if (ret != -EEXIST) {
-			goto fail;
-		}
-
-		ret = remove_from_free_space_tree(trans, disk_bytenr, num_bytes);
-		if (ret)
-			goto fail;
-
-		btrfs_run_delayed_refs(trans, -1);
-		extent_bytenr = disk_bytenr;
-		extent_num_bytes = num_bytes;
-		extent_offset = 0;
-	}
-	btrfs_release_path(path);
-	ins_key.objectid = objectid;
-	ins_key.type = BTRFS_EXTENT_DATA_KEY;
-	ins_key.offset = file_pos;
-	ret = btrfs_insert_empty_item(trans, root, path, &ins_key, sizeof(*fi));
-	if (ret)
-		goto fail;
-	leaf = path->nodes[0];
-	fi = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_file_extent_item);
-	btrfs_set_file_extent_generation(leaf, fi, trans->transid);
-	btrfs_set_file_extent_type(leaf, fi, BTRFS_FILE_EXTENT_REG);
-	btrfs_set_file_extent_disk_bytenr(leaf, fi, extent_bytenr);
-	btrfs_set_file_extent_disk_num_bytes(leaf, fi, extent_num_bytes);
-	btrfs_set_file_extent_offset(leaf, fi, extent_offset);
-	btrfs_set_file_extent_num_bytes(leaf, fi, num_bytes);
-	btrfs_set_file_extent_ram_bytes(leaf, fi, extent_num_bytes);
-	btrfs_set_file_extent_compression(leaf, fi, 0);
-	btrfs_set_file_extent_encryption(leaf, fi, 0);
-	btrfs_set_file_extent_other_encoding(leaf, fi, 0);
-	btrfs_mark_buffer_dirty(leaf);
-
-	nbytes = btrfs_stack_inode_nbytes(inode) + num_bytes;
-	btrfs_set_stack_inode_nbytes(inode, nbytes);
-	btrfs_release_path(path);
-
-	ret = btrfs_inc_extent_ref(trans, extent_bytenr, extent_num_bytes,
-				   0, root->root_key.objectid, objectid,
-				   file_pos - extent_offset);
-	if (ret)
-		goto fail;
-	ret = 0;
-	*ret_num_bytes = min(extent_num_bytes - extent_offset, num_bytes);
-fail:
-	btrfs_free_path(path);
-	return ret;
-}
-
-/*
- * Record a file extent. Do all the required works, such as inserting file
- * extent item, inserting extent item and backref item into extent tree and
- * updating block accounting.
- */
-int btrfs_record_file_extent(struct btrfs_trans_handle *trans,
-			     struct btrfs_root *root, u64 objectid,
-			     struct btrfs_inode_item *inode,
-			     u64 file_pos, u64 disk_bytenr,
-			     u64 num_bytes)
-{
-	u64 cur_disk_bytenr = disk_bytenr;
-	u64 cur_file_pos = file_pos;
-	u64 cur_num_bytes = num_bytes;
-	int ret = 0;
-
-	while (num_bytes > 0) {
-		ret = __btrfs_record_file_extent(trans, root, objectid,
-						 inode, cur_file_pos,
-						 cur_disk_bytenr,
-						 &cur_num_bytes);
-		if (ret < 0)
-			break;
-		cur_disk_bytenr += cur_num_bytes;
-		cur_file_pos += cur_num_bytes;
-		num_bytes -= cur_num_bytes;
-	}
-	return ret;
-}
diff --git a/common/extent-tree-utils.h b/common/extent-tree-utils.h
index f03d9c438375..e9d121345276 100644
--- a/common/extent-tree-utils.h
+++ b/common/extent-tree-utils.h
@@ -27,10 +27,5 @@ struct btrfs_trans_handle;
 
 int btrfs_next_extent_item(struct btrfs_root *root, struct btrfs_path *path,
 			   u64 max_objectid);
-int btrfs_record_file_extent(struct btrfs_trans_handle *trans,
-			     struct btrfs_root *root, u64 objectid,
-			     struct btrfs_inode_item *inode,
-			     u64 file_pos, u64 disk_bytenr,
-			     u64 num_bytes);
 
 #endif
diff --git a/convert/common.c b/convert/common.c
index b093fdb5f14f..0ec9f2ec193f 100644
--- a/convert/common.c
+++ b/convert/common.c
@@ -27,10 +27,13 @@
 #include "kernel-shared/disk-io.h"
 #include "kernel-shared/volumes.h"
 #include "kernel-shared/accessors.h"
-#include "kernel-shared/uapi/btrfs_tree.h"
+#include "kernel-shared/file-item.h"
+#include "kernel-shared/transaction.h"
+#include "kernel-shared/free-space-tree.h"
 #include "common/path-utils.h"
 #include "common/messages.h"
 #include "common/string-utils.h"
+#include "common/extent-tree-utils.h"
 #include "common/fsfeatures.h"
 #include "mkfs/common.h"
 #include "convert/common.h"
@@ -908,3 +911,240 @@ out:
 	return ret;
 }
 
+static void __get_extent_size(struct btrfs_root *root, struct btrfs_path *path,
+			      u64 *start, u64 *len)
+{
+	struct btrfs_key key;
+
+	btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);
+	BUG_ON(!(key.type == BTRFS_EXTENT_ITEM_KEY ||
+		 key.type == BTRFS_METADATA_ITEM_KEY));
+	*start = key.objectid;
+	if (key.type == BTRFS_EXTENT_ITEM_KEY)
+		*len = key.offset;
+	else
+		*len = root->fs_info->nodesize;
+}
+
+/*
+ * Find first overlap extent for range [bytenr, bytenr + len).
+ *
+ * Return 0 for found and point path to it.
+ * Return >0 for not found.
+ * Return <0 for err
+ */
+static int btrfs_search_overlap_extent(struct btrfs_root *root,
+				       struct btrfs_path *path, u64 bytenr, u64 len)
+{
+	struct btrfs_key key;
+	u64 cur_start;
+	u64 cur_len;
+	int ret;
+
+	key.objectid = bytenr;
+	key.type = BTRFS_EXTENT_DATA_KEY;
+	key.offset = (u64)-1;
+
+	ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
+	if (ret < 0)
+		return ret;
+	if (ret == 0) {
+		error_msg(ERROR_MSG_UNEXPECTED, "EXTENT_DATA found at %llu", bytenr);
+		return -EUCLEAN;
+	}
+
+	ret = btrfs_previous_extent_item(root, path, 0);
+	if (ret < 0)
+		return ret;
+	/* No previous, check next extent. */
+	if (ret > 0)
+		goto next;
+	__get_extent_size(root, path, &cur_start, &cur_len);
+	/* Tail overlap. */
+	if (cur_start + cur_len > bytenr)
+		return 1;
+
+next:
+	ret = btrfs_next_extent_item(root, path, bytenr + len);
+	if (ret < 0)
+		return ret;
+	/* No next, prev already checked, no overlap. */
+	if (ret > 0)
+		return 0;
+	__get_extent_size(root, path, &cur_start, &cur_len);
+	/* Head overlap.*/
+	if (cur_start < bytenr + len)
+		return 1;
+	return 0;
+}
+
+static int __btrfs_convert_file_extent(struct btrfs_trans_handle *trans,
+				       struct btrfs_root *root, u64 objectid,
+				       struct btrfs_inode_item *inode,
+				       u64 file_pos, u64 disk_bytenr,
+				       u64 *ret_num_bytes)
+{
+	int ret;
+	struct btrfs_fs_info *info = root->fs_info;
+	struct btrfs_root *extent_root = btrfs_extent_root(info, disk_bytenr);
+	struct extent_buffer *leaf;
+	struct btrfs_file_extent_item *fi;
+	struct btrfs_key ins_key;
+	struct btrfs_path *path;
+	struct btrfs_extent_item *ei;
+	u64 nbytes;
+	u64 extent_num_bytes;
+	u64 extent_bytenr;
+	u64 extent_offset;
+	u64 num_bytes = *ret_num_bytes;
+
+	/*
+	 * @objectid should be an inode number, thus it must not be smaller
+	 * than BTRFS_FIRST_FREE_OBJECTID.
+	 */
+	UASSERT(objectid >= BTRFS_FIRST_FREE_OBJECTID);
+
+	/*
+	 * 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,
+					       file_pos, disk_bytenr,
+					       num_bytes, num_bytes);
+		return ret;
+	}
+	num_bytes = min_t(u64, num_bytes, BTRFS_MAX_EXTENT_SIZE);
+
+	path = btrfs_alloc_path();
+	if (!path)
+		return -ENOMEM;
+
+	/* First to check extent overlap. */
+	ret = btrfs_search_overlap_extent(extent_root, path, disk_bytenr, num_bytes);
+	if (ret < 0)
+		goto fail;
+	if (ret > 0) {
+		/* Found overlap. */
+		u64 cur_start;
+		u64 cur_len;
+
+		__get_extent_size(extent_root, path, &cur_start, &cur_len);
+		/* For convert case, this extent should be a subset of existing one. */
+		if (disk_bytenr < cur_start) {
+			error_msg(ERROR_MSG_UNEXPECTED,
+				  "invalid range disk_bytenr < cur_start: %llu < %llu",
+				  disk_bytenr, cur_start);
+			ret = -EUCLEAN;
+			goto fail;
+		}
+
+		extent_bytenr = cur_start;
+		extent_num_bytes = cur_len;
+		extent_offset = disk_bytenr - extent_bytenr;
+	} else {
+		/* No overlap, create new extent. */
+		btrfs_release_path(path);
+		ins_key.objectid = disk_bytenr;
+		ins_key.type = BTRFS_EXTENT_ITEM_KEY;
+		ins_key.offset = num_bytes;
+
+		ret = btrfs_insert_empty_item(trans, extent_root, path,
+					      &ins_key, sizeof(*ei));
+		if (ret == 0) {
+			leaf = path->nodes[0];
+			ei = btrfs_item_ptr(leaf, path->slots[0],
+					    struct btrfs_extent_item);
+
+			btrfs_set_extent_refs(leaf, ei, 0);
+			btrfs_set_extent_generation(leaf, ei, trans->transid);
+			btrfs_set_extent_flags(leaf, ei,
+					       BTRFS_EXTENT_FLAG_DATA);
+			btrfs_mark_buffer_dirty(leaf);
+
+			ret = btrfs_update_block_group(trans, disk_bytenr,
+						       num_bytes, 1, 0);
+			if (ret)
+				goto fail;
+		} else if (ret != -EEXIST) {
+			goto fail;
+		}
+
+		ret = remove_from_free_space_tree(trans, disk_bytenr, num_bytes);
+		if (ret)
+			goto fail;
+
+		btrfs_run_delayed_refs(trans, -1);
+		extent_bytenr = disk_bytenr;
+		extent_num_bytes = num_bytes;
+		extent_offset = 0;
+	}
+	btrfs_release_path(path);
+	ins_key.objectid = objectid;
+	ins_key.type = BTRFS_EXTENT_DATA_KEY;
+	ins_key.offset = file_pos;
+	ret = btrfs_insert_empty_item(trans, root, path, &ins_key, sizeof(*fi));
+	if (ret)
+		goto fail;
+	leaf = path->nodes[0];
+	fi = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_file_extent_item);
+	btrfs_set_file_extent_generation(leaf, fi, trans->transid);
+	btrfs_set_file_extent_type(leaf, fi, BTRFS_FILE_EXTENT_REG);
+	btrfs_set_file_extent_disk_bytenr(leaf, fi, extent_bytenr);
+	btrfs_set_file_extent_disk_num_bytes(leaf, fi, extent_num_bytes);
+	btrfs_set_file_extent_offset(leaf, fi, extent_offset);
+	btrfs_set_file_extent_num_bytes(leaf, fi, num_bytes);
+	btrfs_set_file_extent_ram_bytes(leaf, fi, extent_num_bytes);
+	btrfs_set_file_extent_compression(leaf, fi, 0);
+	btrfs_set_file_extent_encryption(leaf, fi, 0);
+	btrfs_set_file_extent_other_encoding(leaf, fi, 0);
+	btrfs_mark_buffer_dirty(leaf);
+
+	nbytes = btrfs_stack_inode_nbytes(inode) + num_bytes;
+	btrfs_set_stack_inode_nbytes(inode, nbytes);
+	btrfs_release_path(path);
+
+	ret = btrfs_inc_extent_ref(trans, extent_bytenr, extent_num_bytes,
+				   0, root->root_key.objectid, objectid,
+				   file_pos - extent_offset);
+	if (ret)
+		goto fail;
+	ret = 0;
+	*ret_num_bytes = min(extent_num_bytes - extent_offset, num_bytes);
+fail:
+	btrfs_free_path(path);
+	return ret;
+}
+
+/*
+ * Insert file extent using converted image. Do all the required works,
+ * such as inserting file extent item, inserting extent item and backref item
+ * into extent tree and updating block accounting.
+ *
+ * This is for btrfs-convert only, thus it won't support compressed regular
+ * file extents.
+ */
+int btrfs_convert_file_extent(struct btrfs_trans_handle *trans,
+			      struct btrfs_root *root, u64 objectid,
+			      struct btrfs_inode_item *inode,
+			      u64 file_pos, u64 disk_bytenr,
+			      u64 num_bytes)
+{
+	u64 cur_disk_bytenr = disk_bytenr;
+	u64 cur_file_pos = file_pos;
+	u64 cur_num_bytes = num_bytes;
+	int ret = 0;
+
+	while (num_bytes > 0) {
+		ret = __btrfs_convert_file_extent(trans, root, objectid,
+						  inode, cur_file_pos,
+						  cur_disk_bytenr,
+						  &cur_num_bytes);
+		if (ret < 0)
+			break;
+		cur_disk_bytenr += cur_num_bytes;
+		cur_file_pos += cur_num_bytes;
+		num_bytes -= cur_num_bytes;
+	}
+	return ret;
+}
diff --git a/convert/common.h b/convert/common.h
index 581ef3298304..7678c1656507 100644
--- a/convert/common.h
+++ b/convert/common.h
@@ -23,6 +23,7 @@
 #define __BTRFS_CONVERT_COMMON_H__
 
 #include "kerncompat.h"
+#include "kernel-shared/uapi/btrfs_tree.h"
 #include "common/extent-cache.h"
 
 struct btrfs_mkfs_config;
@@ -84,4 +85,9 @@ static inline u64 range_end(const struct simple_range *range)
 	return (range->start + range->len);
 }
 
+int btrfs_convert_file_extent(struct btrfs_trans_handle *trans,
+			      struct btrfs_root *root, u64 objectid,
+			      struct btrfs_inode_item *inode,
+			      u64 file_pos, u64 disk_bytenr,
+			      u64 num_bytes);
 #endif
diff --git a/convert/main.c b/convert/main.c
index a227cc6fef84..805682705dff 100644
--- a/convert/main.c
+++ b/convert/main.c
@@ -337,7 +337,7 @@ static int create_image_file_range(struct btrfs_trans_handle *trans,
 		error("remaining length not sectorsize aligned: %llu", len);
 		return -EINVAL;
 	}
-	ret = btrfs_record_file_extent(trans, root, ino, inode, bytenr,
+	ret = btrfs_convert_file_extent(trans, root, ino, inode, bytenr,
 				       disk_bytenr, len);
 	if (ret < 0)
 		return ret;
@@ -426,8 +426,8 @@ static int migrate_one_reserved_range(struct btrfs_trans_handle *trans,
 			break;
 
 		/* Now handle extent item and file extent things */
-		ret = btrfs_record_file_extent(trans, root, ino, inode, cur_off,
-					       key.objectid, key.offset);
+		ret = btrfs_convert_file_extent(trans, root, ino, inode, cur_off,
+					        key.objectid, key.offset);
 		if (ret < 0)
 			break;
 		/* Finally, insert csum items */
@@ -438,7 +438,7 @@ static int migrate_one_reserved_range(struct btrfs_trans_handle *trans,
 		/* Don't forget to insert hole */
 		hole_len = cur_off - hole_start;
 		if (hole_len) {
-			ret = btrfs_record_file_extent(trans, root, ino, inode,
+			ret = btrfs_convert_file_extent(trans, root, ino, inode,
 					hole_start, 0, hole_len);
 			if (ret < 0)
 				break;
@@ -455,7 +455,7 @@ static int migrate_one_reserved_range(struct btrfs_trans_handle *trans,
 	 *                   | Hole |
 	 */
 	if (range_end(range) - hole_start > 0)
-		ret = btrfs_record_file_extent(trans, root, ino, inode,
+		ret = btrfs_convert_file_extent(trans, root, ino, inode,
 				hole_start, 0, range_end(range) - hole_start);
 	return ret;
 }
diff --git a/convert/source-fs.c b/convert/source-fs.c
index 97c989d9ab13..8a296bd9c7f4 100644
--- a/convert/source-fs.c
+++ b/convert/source-fs.c
@@ -260,7 +260,7 @@ int record_file_blocks(struct blk_iterate_data *data,
 
 	/* Hole, pass it to record_file_extent directly */
 	if (old_disk_bytenr == 0)
-		return btrfs_record_file_extent(data->trans, root,
+		return btrfs_convert_file_extent(data->trans, root,
 				data->objectid, data->inode, file_pos, 0,
 				num_bytes);
 
@@ -314,7 +314,7 @@ int record_file_blocks(struct blk_iterate_data *data,
 			real_disk_bytenr = 0;
 		cur_len = min(key.offset + extent_num_bytes,
 			      old_disk_bytenr + num_bytes) - cur_off;
-		ret = btrfs_record_file_extent(data->trans, data->root,
+		ret = btrfs_convert_file_extent(data->trans, data->root,
 					data->objectid, data->inode, file_pos,
 					real_disk_bytenr, cur_len);
 		if (ret < 0)
diff --git a/convert/source-reiserfs.c b/convert/source-reiserfs.c
index 3475b15277dc..32d60c09fb0c 100644
--- a/convert/source-reiserfs.c
+++ b/convert/source-reiserfs.c
@@ -364,7 +364,7 @@ static int convert_direct(struct btrfs_trans_handle *trans,
 	if (ret)
 		return ret;
 
-	return btrfs_record_file_extent(trans, root, objectid, inode, offset,
+	return btrfs_convert_file_extent(trans, root, objectid, inode, offset,
 					key.objectid, sectorsize);
 }
 
diff --git a/mkfs/rootdir.c b/mkfs/rootdir.c
index ffe9aa1f9af1..526fa255306f 100644
--- a/mkfs/rootdir.c
+++ b/mkfs/rootdir.c
@@ -36,6 +36,7 @@
 #include "kernel-shared/disk-io.h"
 #include "kernel-shared/transaction.h"
 #include "kernel-shared/file-item.h"
+#include "kernel-shared/free-space-tree.h"
 #include "common/internal.h"
 #include "common/messages.h"
 #include "common/utils.h"
@@ -362,6 +363,98 @@ fail:
 	return ret;
 }
 
+static int insert_reserved_file_extent(struct btrfs_trans_handle *trans,
+				       struct btrfs_root *root, u64 ino,
+				       struct btrfs_inode_item *inode,
+				       u64 file_pos, u64 disk_bytenr,
+				       u64 num_bytes)
+{
+	struct btrfs_fs_info *fs_info = root->fs_info;
+	struct btrfs_root *extent_root = btrfs_extent_root(fs_info, disk_bytenr);
+	struct extent_buffer *leaf;
+	struct btrfs_key ins_key;
+	struct btrfs_path *path;
+	struct btrfs_extent_item *ei;
+	int ret;
+
+	/*
+	 * @ino should be an inode number, thus it must not be smaller
+	 * than BTRFS_FIRST_FREE_OBJECTID.
+	 */
+	UASSERT(ino >= BTRFS_FIRST_FREE_OBJECTID);
+
+	/* The reserved data extent should never exceed the upper limit. */
+	UASSERT(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, ino,
+					       file_pos, disk_bytenr,
+					       num_bytes, num_bytes);
+		return ret;
+	}
+
+	path = btrfs_alloc_path();
+	if (!path)
+		return -ENOMEM;
+
+	ins_key.objectid = disk_bytenr;
+	ins_key.type = BTRFS_EXTENT_ITEM_KEY;
+	ins_key.offset = num_bytes;
+
+	/* Update extent tree. */
+	ret = btrfs_insert_empty_item(trans, extent_root, path,
+				      &ins_key, sizeof(*ei));
+	if (ret == 0) {
+		leaf = path->nodes[0];
+		ei = btrfs_item_ptr(leaf, path->slots[0],
+				    struct btrfs_extent_item);
+
+		btrfs_set_extent_refs(leaf, ei, 0);
+		btrfs_set_extent_generation(leaf, ei, trans->transid);
+		btrfs_set_extent_flags(leaf, ei,
+				       BTRFS_EXTENT_FLAG_DATA);
+		btrfs_mark_buffer_dirty(leaf);
+
+		ret = btrfs_update_block_group(trans, disk_bytenr,
+					       num_bytes, 1, 0);
+		if (ret)
+			goto fail;
+	} else if (ret != -EEXIST) {
+		goto fail;
+	}
+	btrfs_release_path(path);
+
+	ret = remove_from_free_space_tree(trans, disk_bytenr, num_bytes);
+	if (ret)
+		goto fail;
+
+	btrfs_run_delayed_refs(trans, -1);
+
+	ins_key.objectid = ino;
+	ins_key.type = BTRFS_EXTENT_DATA_KEY;
+	ins_key.offset = file_pos;
+	ret = btrfs_insert_file_extent(trans, root, ino, file_pos, disk_bytenr,
+				       num_bytes, num_bytes);
+	if (ret)
+		goto fail;
+	btrfs_set_stack_inode_nbytes(inode,
+			btrfs_stack_inode_nbytes(inode) + num_bytes);
+
+	ret = btrfs_inc_extent_ref(trans, disk_bytenr, num_bytes,
+				   0, root->root_key.objectid, ino,
+				   file_pos);
+	if (ret)
+		goto fail;
+	ret = 0;
+fail:
+	btrfs_free_path(path);
+	return ret;
+}
+
 static int add_file_items(struct btrfs_trans_handle *trans,
 			  struct btrfs_root *root,
 			  struct btrfs_inode_item *btrfs_inode, u64 objectid,
@@ -471,7 +564,7 @@ again:
 	}
 
 	if (bytes_read) {
-		ret = btrfs_record_file_extent(trans, root, objectid,
+		ret = insert_reserved_file_extent(trans, root, objectid,
 				btrfs_inode, file_pos, first_block, cur_bytes);
 		if (ret)
 			goto end;
