@@ -151,37 +151,55 @@ static int recow_roots(struct btrfs_trans_handle *trans,
int ret;
struct extent_buffer *tmp;
struct btrfs_fs_info *info = root->fs_info;
+ u64 generation;
- ret = __btrfs_cow_block(trans, info->fs_root, info->fs_root->node,
- NULL, 0, &tmp, 0, 0);
- BUG_ON(ret);
- free_extent_buffer(tmp);
+ generation = btrfs_root_generation(&info->fs_root->root_item);
+ if (generation != trans->transid) {
+ ret = __btrfs_cow_block(trans, info->fs_root,
+ info->fs_root->node, NULL, 0, &tmp, 0, 0);
+ BUG_ON(ret);
+ free_extent_buffer(tmp);
+ }
- ret = __btrfs_cow_block(trans, info->tree_root, info->tree_root->node,
- NULL, 0, &tmp, 0, 0);
- BUG_ON(ret);
- free_extent_buffer(tmp);
+ generation = btrfs_root_generation(&info->tree_root->root_item);
+ if (generation != trans->transid) {
+ ret = __btrfs_cow_block(trans, info->tree_root,
+ info->tree_root->node, NULL, 0, &tmp, 0, 0);
+ BUG_ON(ret);
+ free_extent_buffer(tmp);
+ }
- ret = __btrfs_cow_block(trans, info->extent_root,
+ generation = btrfs_root_generation(&info->extent_root->root_item);
+ if (generation != trans->transid) {
+ ret = __btrfs_cow_block(trans, info->extent_root,
info->extent_root->node, NULL, 0, &tmp, 0, 0);
- BUG_ON(ret);
- free_extent_buffer(tmp);
-
- ret = __btrfs_cow_block(trans, info->chunk_root, info->chunk_root->node,
- NULL, 0, &tmp, 0, 0);
- BUG_ON(ret);
- free_extent_buffer(tmp);
+ BUG_ON(ret);
+ free_extent_buffer(tmp);
+ }
+ generation = btrfs_root_generation(&info->chunk_root->root_item);
+ if (generation != trans->transid) {
+ ret = __btrfs_cow_block(trans, info->chunk_root,
+ info->chunk_root->node, NULL, 0, &tmp, 0, 0);
+ BUG_ON(ret);
+ free_extent_buffer(tmp);
+ }
- ret = __btrfs_cow_block(trans, info->dev_root, info->dev_root->node,
- NULL, 0, &tmp, 0, 0);
- BUG_ON(ret);
- free_extent_buffer(tmp);
+ generation = btrfs_root_generation(&info->dev_root->root_item);
+ if (generation != trans->transid) {
+ ret = __btrfs_cow_block(trans, info->dev_root,
+ info->dev_root->node, NULL, 0, &tmp, 0, 0);
+ BUG_ON(ret);
+ free_extent_buffer(tmp);
+ }
- ret = __btrfs_cow_block(trans, info->csum_root, info->csum_root->node,
- NULL, 0, &tmp, 0, 0);
- BUG_ON(ret);
- free_extent_buffer(tmp);
+ generation = btrfs_root_generation(&info->csum_root->root_item);
+ if (generation != trans->transid) {
+ ret = __btrfs_cow_block(trans, info->csum_root,
+ info->csum_root->node, NULL, 0, &tmp, 0, 0);
+ BUG_ON(ret);
+ free_extent_buffer(tmp);
+ }
return 0;
}
@@ -281,8 +299,6 @@ static int create_raid_groups(struct btrfs_trans_handle *trans,
(allowed & metadata_profile));
BUG_ON(ret);
- ret = recow_roots(trans, root);
- BUG_ON(ret);
}
if (!mixed && num_devices > 1 && (allowed & data_profile)) {
ret = create_one_raid_group(trans, root,
@@ -290,6 +306,9 @@ static int create_raid_groups(struct btrfs_trans_handle *trans,
(allowed & data_profile));
BUG_ON(ret);
}
+ ret = recow_roots(trans, root);
+ BUG_ON(ret);
+
return 0;
}