@@ -4511,6 +4511,7 @@ static int process_extent(struct send_ctx *sctx,
struct btrfs_key *key)
{
struct clone_root *found_clone = NULL;
+ struct btrfs_trans_handle *trans;
int ret = 0;
if (S_ISLNK(sctx->cur_inode_mode))
@@ -4551,10 +4552,24 @@ static int process_extent(struct send_ctx *sctx,
}
}
}
+ /*
+ * We need to make sure the transaction does not get committed
+ * while we are walking backrefs on extent commit root.
+ */
+ trans = btrfs_join_transaction(sctx->send_root);
+ if (IS_ERR(trans)) {
+ ret = PTR_ERR(trans);
+ goto out;
+ }
ret = find_extent_clone(sctx, path, key->objectid, key->offset,
sctx->cur_inode_size, &found_clone);
- if (ret != -ENOENT && ret < 0)
+ if (ret != -ENOENT && ret < 0) {
+ btrfs_end_transaction(trans, sctx->send_root);
+ goto out;
+ }
+ ret = btrfs_end_transaction(trans, sctx->send_root);
+ if (ret)
goto out;
ret = send_write_or_clone(sctx, path, key, found_clone);