@@ -71,6 +71,7 @@
#include "backref.h"
#include "raid-stripe-tree.h"
#include "fiemap.h"
+#include "volumes.h"
struct btrfs_iget_args {
u64 ino;
@@ -8679,6 +8680,44 @@ static int btrfs_symlink(struct mnt_idmap *idmap, struct inode *dir,
return err;
}
+static int insert_prealloc_rst_entry(struct btrfs_fs_info *fs_info,
+ struct btrfs_trans_handle *trans_in,
+ u64 start, u64 len)
+{
+ struct btrfs_trans_handle *trans;
+ struct btrfs_chunk_map *map;
+ u64 map_type;
+ int ret;
+
+ if (!btrfs_fs_incompat(fs_info, RAID_STRIPE_TREE))
+ return 0;
+
+ if (trans_in)
+ trans = trans_in;
+ else
+ trans = btrfs_join_transaction(fs_info->stripe_root);
+
+ map = btrfs_find_chunk_map(fs_info, start, len);
+ if (!map)
+ return -ENOENT;
+
+ map_type = map->type;
+ btrfs_free_chunk_map(map);
+
+ if (!btrfs_need_stripe_tree_update(fs_info, map_type))
+ return 0;
+ ret = btrfs_insert_dummy_raid_extent(trans, start, len);
+ if (ret) {
+ btrfs_abort_transaction(trans, ret);
+ return ret;
+ }
+
+ if (trans != trans_in)
+ btrfs_end_transaction(trans);
+
+ return 0;
+}
+
static struct btrfs_trans_handle *insert_prealloc_file_extent(
struct btrfs_trans_handle *trans_in,
struct btrfs_inode *inode,
@@ -8817,6 +8856,14 @@ static int __btrfs_prealloc_file_range(struct inode *inode, int mode,
break;
}
+ ret = insert_prealloc_rst_entry(fs_info, trans, ins.objectid,
+ cur_offset);
+ if (ret) {
+ btrfs_free_reserved_extent(fs_info, ins.objectid,
+ ins.offset, 0);
+ break;
+ }
+
em = alloc_extent_map();
if (!em) {
btrfs_drop_extent_map_range(BTRFS_I(inode), cur_offset,
@@ -61,6 +61,9 @@ int btrfs_delete_raid_extent(struct btrfs_trans_handle *trans, u64 start, u64 le
trace_btrfs_raid_extent_delete(fs_info, start, end,
found_start, found_end);
+ if (key.type == BTRFS_RAID_STRIPE_DUMMY_KEY)
+ goto delete;
+
if (found_start < start) {
struct btrfs_key prev;
u64 diff = start - found_start;
@@ -112,6 +115,7 @@ int btrfs_delete_raid_extent(struct btrfs_trans_handle *trans, u64 start, u64 le
break;
}
+delete:
ret = btrfs_del_item(trans, stripe_root, path);
if (ret)
break;