diff --git a/convert/common.c b/convert/common.c
index 0ec9f2ec193f..802b809ca837 100644
--- a/convert/common.c
+++ b/convert/common.c
@@ -987,8 +987,7 @@ static int __btrfs_convert_file_extent(struct btrfs_trans_handle *trans,
 	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_file_extent_item stack_fi = { 0 };
 	struct btrfs_key ins_key;
 	struct btrfs_path *path;
 	struct btrfs_extent_item *ei;
@@ -1009,9 +1008,11 @@ static int __btrfs_convert_file_extent(struct btrfs_trans_handle *trans,
 	 * hole.  And hole extent has no size limit, no need to loop.
 	 */
 	if (disk_bytenr == 0) {
+		btrfs_set_stack_file_extent_type(&stack_fi, BTRFS_FILE_EXTENT_REG);
+		btrfs_set_stack_file_extent_num_bytes(&stack_fi, num_bytes);
+		btrfs_set_stack_file_extent_ram_bytes(&stack_fi, num_bytes);
 		ret = btrfs_insert_file_extent(trans, root, objectid,
-					       file_pos, disk_bytenr,
-					       num_bytes, num_bytes);
+					       file_pos, &stack_fi);
 		return ret;
 	}
 	num_bytes = min_t(u64, num_bytes, BTRFS_MAX_EXTENT_SIZE);
@@ -1052,6 +1053,8 @@ static int __btrfs_convert_file_extent(struct btrfs_trans_handle *trans,
 		ret = btrfs_insert_empty_item(trans, extent_root, path,
 					      &ins_key, sizeof(*ei));
 		if (ret == 0) {
+			struct extent_buffer *leaf;
+
 			leaf = path->nodes[0];
 			ei = btrfs_item_ptr(leaf, path->slots[0],
 					    struct btrfs_extent_item);
@@ -1083,26 +1086,18 @@ static int __btrfs_convert_file_extent(struct btrfs_trans_handle *trans,
 	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));
+	btrfs_set_stack_file_extent_type(&stack_fi, BTRFS_FILE_EXTENT_REG);
+	btrfs_set_stack_file_extent_disk_bytenr(&stack_fi, extent_bytenr);
+	btrfs_set_stack_file_extent_disk_num_bytes(&stack_fi, extent_num_bytes);
+	btrfs_set_stack_file_extent_offset(&stack_fi, extent_offset);
+	btrfs_set_stack_file_extent_num_bytes(&stack_fi, num_bytes);
+	btrfs_set_stack_file_extent_ram_bytes(&stack_fi, extent_num_bytes);
+	ret = btrfs_insert_file_extent(trans, root, objectid, file_pos, &stack_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,
diff --git a/kernel-shared/file-item.c b/kernel-shared/file-item.c
index eb9024022d9f..0de2a216c54d 100644
--- a/kernel-shared/file-item.c
+++ b/kernel-shared/file-item.c
@@ -33,55 +33,31 @@
 			       size) - 1))
 int btrfs_insert_file_extent(struct btrfs_trans_handle *trans,
 			     struct btrfs_root *root,
-			     u64 objectid, u64 pos, u64 offset,
-			     u64 disk_num_bytes, u64 num_bytes)
+			     u64 ino, u64 file_pos,
+			     struct btrfs_file_extent_item *stack_fi)
 {
 	int ret = 0;
 	int is_hole = 0;
-	struct btrfs_file_extent_item *item;
 	struct btrfs_key file_key;
-	struct btrfs_path *path;
-	struct extent_buffer *leaf;
 
-	if (offset == 0)
+	if (btrfs_stack_file_extent_disk_bytenr(stack_fi) == 0)
 		is_hole = 1;
+
 	/* For NO_HOLES, we don't insert hole file extent */
 	if (btrfs_fs_incompat(root->fs_info, NO_HOLES) && is_hole)
 		return 0;
 
 	/* For hole, its disk_bytenr and disk_num_bytes must be 0 */
 	if (is_hole)
-		disk_num_bytes = 0;
+		btrfs_set_stack_file_extent_disk_num_bytes(stack_fi, 0);
 
-	path = btrfs_alloc_path();
-	if (!path)
-		return -ENOMEM;
-
-	file_key.objectid = objectid;
+	file_key.objectid = ino;
 	file_key.type = BTRFS_EXTENT_DATA_KEY;
-	file_key.offset = pos;
+	file_key.offset = file_pos;
 
-	ret = btrfs_insert_empty_item(trans, root, path, &file_key,
-				      sizeof(*item));
-	if (ret < 0)
-		goto out;
-	BUG_ON(ret);
-	leaf = path->nodes[0];
-	item = btrfs_item_ptr(leaf, path->slots[0],
-			      struct btrfs_file_extent_item);
-	btrfs_set_file_extent_disk_bytenr(leaf, item, offset);
-	btrfs_set_file_extent_disk_num_bytes(leaf, item, disk_num_bytes);
-	btrfs_set_file_extent_offset(leaf, item, 0);
-	btrfs_set_file_extent_num_bytes(leaf, item, num_bytes);
-	btrfs_set_file_extent_ram_bytes(leaf, item, num_bytes);
-	btrfs_set_file_extent_generation(leaf, item, trans->transid);
-	btrfs_set_file_extent_type(leaf, item, BTRFS_FILE_EXTENT_REG);
-	btrfs_set_file_extent_compression(leaf, item, 0);
-	btrfs_set_file_extent_encryption(leaf, item, 0);
-	btrfs_set_file_extent_other_encoding(leaf, item, 0);
-	btrfs_mark_buffer_dirty(leaf);
-out:
-	btrfs_free_path(path);
+	btrfs_set_stack_file_extent_generation(stack_fi, trans->transid);
+	ret = btrfs_insert_item(trans, root, &file_key, stack_fi,
+				sizeof(struct btrfs_file_extent_item));
 	return ret;
 }
 
diff --git a/kernel-shared/file-item.h b/kernel-shared/file-item.h
index 2c1e17c990dc..cb38a1fc0296 100644
--- a/kernel-shared/file-item.h
+++ b/kernel-shared/file-item.h
@@ -85,8 +85,8 @@ u64 btrfs_file_extent_end(const struct btrfs_path *path);
  */
 int btrfs_insert_file_extent(struct btrfs_trans_handle *trans,
 			     struct btrfs_root *root,
-			     u64 objectid, u64 pos, u64 offset,
-			     u64 disk_num_bytes, u64 num_bytes);
+			     u64 ino, u64 file_pos,
+			     struct btrfs_file_extent_item *stack_fi);
 int btrfs_csum_file_block(struct btrfs_trans_handle *trans, u64 logical,
 			  u64 csum_objectid, u32 csum_type, const char *data);
 int btrfs_insert_inline_extent(struct btrfs_trans_handle *trans,
diff --git a/kernel-shared/file.c b/kernel-shared/file.c
index 414a01b3ec4b..7ed1b6891795 100644
--- a/kernel-shared/file.c
+++ b/kernel-shared/file.c
@@ -152,6 +152,7 @@ int btrfs_punch_hole(struct btrfs_trans_handle *trans,
 		     u64 ino, u64 offset, u64 len)
 {
 	struct btrfs_path *path;
+	struct btrfs_file_extent_item stack_fi = { 0 };
 	int ret = 0;
 
 	path = btrfs_alloc_path();
@@ -166,7 +167,10 @@ int btrfs_punch_hole(struct btrfs_trans_handle *trans,
 		goto out;
 	}
 
-	ret = btrfs_insert_file_extent(trans, root, ino, offset, 0, 0, len);
+	btrfs_set_stack_file_extent_type(&stack_fi, BTRFS_FILE_EXTENT_REG);
+	btrfs_set_stack_file_extent_num_bytes(&stack_fi, len);
+	btrfs_set_stack_file_extent_ram_bytes(&stack_fi, len);
+	ret = btrfs_insert_file_extent(trans, root, ino, offset, &stack_fi);
 out:
 	btrfs_free_path(path);
 	return ret;
diff --git a/mkfs/rootdir.c b/mkfs/rootdir.c
index 526fa255306f..5fa480886139 100644
--- a/mkfs/rootdir.c
+++ b/mkfs/rootdir.c
@@ -366,17 +366,21 @@ fail:
 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)
+				       u64 file_pos,
+				       struct btrfs_file_extent_item *stack_fi)
 {
 	struct btrfs_fs_info *fs_info = root->fs_info;
-	struct btrfs_root *extent_root = btrfs_extent_root(fs_info, disk_bytenr);
+	struct btrfs_root *extent_root;
 	struct extent_buffer *leaf;
 	struct btrfs_key ins_key;
 	struct btrfs_path *path;
 	struct btrfs_extent_item *ei;
+	u64 disk_bytenr = btrfs_stack_file_extent_disk_bytenr(stack_fi);
+	u64 disk_num_bytes = btrfs_stack_file_extent_disk_num_bytes(stack_fi);
+	u64 num_bytes = btrfs_stack_file_extent_num_bytes(stack_fi);
 	int ret;
 
+	extent_root = btrfs_extent_root(fs_info, disk_bytenr);
 	/*
 	 * @ino should be an inode number, thus it must not be smaller
 	 * than BTRFS_FIRST_FREE_OBJECTID.
@@ -384,18 +388,15 @@ static int insert_reserved_file_extent(struct btrfs_trans_handle *trans,
 	UASSERT(ino >= BTRFS_FIRST_FREE_OBJECTID);
 
 	/* The reserved data extent should never exceed the upper limit. */
-	UASSERT(num_bytes <= BTRFS_MAX_EXTENT_SIZE);
+	UASSERT(disk_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;
-	}
+	if (disk_bytenr == 0)
+		return btrfs_insert_file_extent(trans, root, ino,
+					       file_pos, stack_fi);
 
 	path = btrfs_alloc_path();
 	if (!path)
@@ -437,8 +438,7 @@ static int insert_reserved_file_extent(struct btrfs_trans_handle *trans,
 	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);
+	ret = btrfs_insert_file_extent(trans, root, ino, file_pos, stack_fi);
 	if (ret)
 		goto fail;
 	btrfs_set_stack_inode_nbytes(inode,
@@ -564,8 +564,15 @@ again:
 	}
 
 	if (bytes_read) {
+		struct btrfs_file_extent_item stack_fi = { 0 };
+
+		btrfs_set_stack_file_extent_type(&stack_fi, BTRFS_FILE_EXTENT_REG);
+		btrfs_set_stack_file_extent_disk_bytenr(&stack_fi, first_block);
+		btrfs_set_stack_file_extent_disk_num_bytes(&stack_fi, cur_bytes);
+		btrfs_set_stack_file_extent_num_bytes(&stack_fi, cur_bytes);
+		btrfs_set_stack_file_extent_ram_bytes(&stack_fi, cur_bytes);
 		ret = insert_reserved_file_extent(trans, root, objectid,
-				btrfs_inode, file_pos, first_block, cur_bytes);
+				btrfs_inode, file_pos, &stack_fi);
 		if (ret)
 			goto end;
 
