aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/send.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/send.c')
-rw-r--r--fs/btrfs/send.c57
1 files changed, 2 insertions, 55 deletions
diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index d00534b78382..6b5f13659317 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -1268,8 +1268,10 @@ static int find_extent_clone(struct send_ctx *sctx,
1268 } 1268 }
1269 logical = disk_byte + btrfs_file_extent_offset(eb, fi); 1269 logical = disk_byte + btrfs_file_extent_offset(eb, fi);
1270 1270
1271 down_read(&sctx->send_root->fs_info->commit_root_sem);
1271 ret = extent_from_logical(sctx->send_root->fs_info, disk_byte, tmp_path, 1272 ret = extent_from_logical(sctx->send_root->fs_info, disk_byte, tmp_path,
1272 &found_key, &flags); 1273 &found_key, &flags);
1274 up_read(&sctx->send_root->fs_info->commit_root_sem);
1273 btrfs_release_path(tmp_path); 1275 btrfs_release_path(tmp_path);
1274 1276
1275 if (ret < 0) 1277 if (ret < 0)
@@ -5367,57 +5369,21 @@ out:
5367static int full_send_tree(struct send_ctx *sctx) 5369static int full_send_tree(struct send_ctx *sctx)
5368{ 5370{
5369 int ret; 5371 int ret;
5370 struct btrfs_trans_handle *trans = NULL;
5371 struct btrfs_root *send_root = sctx->send_root; 5372 struct btrfs_root *send_root = sctx->send_root;
5372 struct btrfs_key key; 5373 struct btrfs_key key;
5373 struct btrfs_key found_key; 5374 struct btrfs_key found_key;
5374 struct btrfs_path *path; 5375 struct btrfs_path *path;
5375 struct extent_buffer *eb; 5376 struct extent_buffer *eb;
5376 int slot; 5377 int slot;
5377 u64 start_ctransid;
5378 u64 ctransid;
5379 5378
5380 path = alloc_path_for_send(); 5379 path = alloc_path_for_send();
5381 if (!path) 5380 if (!path)
5382 return -ENOMEM; 5381 return -ENOMEM;
5383 5382
5384 spin_lock(&send_root->root_item_lock);
5385 start_ctransid = btrfs_root_ctransid(&send_root->root_item);
5386 spin_unlock(&send_root->root_item_lock);
5387
5388 key.objectid = BTRFS_FIRST_FREE_OBJECTID; 5383 key.objectid = BTRFS_FIRST_FREE_OBJECTID;
5389 key.type = BTRFS_INODE_ITEM_KEY; 5384 key.type = BTRFS_INODE_ITEM_KEY;
5390 key.offset = 0; 5385 key.offset = 0;
5391 5386
5392join_trans:
5393 /*
5394 * We need to make sure the transaction does not get committed
5395 * while we do anything on commit roots. Join a transaction to prevent
5396 * this.
5397 */
5398 trans = btrfs_join_transaction(send_root);
5399 if (IS_ERR(trans)) {
5400 ret = PTR_ERR(trans);
5401 trans = NULL;
5402 goto out;
5403 }
5404
5405 /*
5406 * Make sure the tree has not changed after re-joining. We detect this
5407 * by comparing start_ctransid and ctransid. They should always match.
5408 */
5409 spin_lock(&send_root->root_item_lock);
5410 ctransid = btrfs_root_ctransid(&send_root->root_item);
5411 spin_unlock(&send_root->root_item_lock);
5412
5413 if (ctransid != start_ctransid) {
5414 WARN(1, KERN_WARNING "BTRFS: the root that you're trying to "
5415 "send was modified in between. This is "
5416 "probably a bug.\n");
5417 ret = -EIO;
5418 goto out;
5419 }
5420
5421 ret = btrfs_search_slot_for_read(send_root, &key, path, 1, 0); 5387 ret = btrfs_search_slot_for_read(send_root, &key, path, 1, 0);
5422 if (ret < 0) 5388 if (ret < 0)
5423 goto out; 5389 goto out;
@@ -5425,19 +5391,6 @@ join_trans:
5425 goto out_finish; 5391 goto out_finish;
5426 5392
5427 while (1) { 5393 while (1) {
5428 /*
5429 * When someone want to commit while we iterate, end the
5430 * joined transaction and rejoin.
5431 */
5432 if (btrfs_should_end_transaction(trans, send_root)) {
5433 ret = btrfs_end_transaction(trans, send_root);
5434 trans = NULL;
5435 if (ret < 0)
5436 goto out;
5437 btrfs_release_path(path);
5438 goto join_trans;
5439 }
5440
5441 eb = path->nodes[0]; 5394 eb = path->nodes[0];
5442 slot = path->slots[0]; 5395 slot = path->slots[0];
5443 btrfs_item_key_to_cpu(eb, &found_key, slot); 5396 btrfs_item_key_to_cpu(eb, &found_key, slot);
@@ -5465,12 +5418,6 @@ out_finish:
5465 5418
5466out: 5419out:
5467 btrfs_free_path(path); 5420 btrfs_free_path(path);
5468 if (trans) {
5469 if (!ret)
5470 ret = btrfs_end_transaction(trans, send_root);
5471 else
5472 btrfs_end_transaction(trans, send_root);
5473 }
5474 return ret; 5421 return ret;
5475} 5422}
5476 5423