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.c77
1 files changed, 15 insertions, 62 deletions
diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index 69b59bf75882..c3c0c064c25d 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -6322,68 +6322,21 @@ static int changed_extent(struct send_ctx *sctx,
6322{ 6322{
6323 int ret = 0; 6323 int ret = 0;
6324 6324
6325 if (sctx->cur_ino != sctx->cmp_key->objectid) { 6325 /*
6326 6326 * We have found an extent item that changed without the inode item
6327 if (result == BTRFS_COMPARE_TREE_CHANGED) { 6327 * having changed. This can happen either after relocation (where the
6328 struct extent_buffer *leaf_l; 6328 * disk_bytenr of an extent item is replaced at
6329 struct extent_buffer *leaf_r; 6329 * relocation.c:replace_file_extents()) or after deduplication into a
6330 struct btrfs_file_extent_item *ei_l; 6330 * file in both the parent and send snapshots (where an extent item can
6331 struct btrfs_file_extent_item *ei_r; 6331 * get modified or replaced with a new one). Note that deduplication
6332 6332 * updates the inode item, but it only changes the iversion (sequence
6333 leaf_l = sctx->left_path->nodes[0]; 6333 * field in the inode item) of the inode, so if a file is deduplicated
6334 leaf_r = sctx->right_path->nodes[0]; 6334 * the same amount of times in both the parent and send snapshots, its
6335 ei_l = btrfs_item_ptr(leaf_l, 6335 * iversion becames the same in both snapshots, whence the inode item is
6336 sctx->left_path->slots[0], 6336 * the same on both snapshots.
6337 struct btrfs_file_extent_item); 6337 */
6338 ei_r = btrfs_item_ptr(leaf_r, 6338 if (sctx->cur_ino != sctx->cmp_key->objectid)
6339 sctx->right_path->slots[0], 6339 return 0;
6340 struct btrfs_file_extent_item);
6341
6342 /*
6343 * We may have found an extent item that has changed
6344 * only its disk_bytenr field and the corresponding
6345 * inode item was not updated. This case happens due to
6346 * very specific timings during relocation when a leaf
6347 * that contains file extent items is COWed while
6348 * relocation is ongoing and its in the stage where it
6349 * updates data pointers. So when this happens we can
6350 * safely ignore it since we know it's the same extent,
6351 * but just at different logical and physical locations
6352 * (when an extent is fully replaced with a new one, we
6353 * know the generation number must have changed too,
6354 * since snapshot creation implies committing the current
6355 * transaction, and the inode item must have been updated
6356 * as well).
6357 * This replacement of the disk_bytenr happens at
6358 * relocation.c:replace_file_extents() through
6359 * relocation.c:btrfs_reloc_cow_block().
6360 */
6361 if (btrfs_file_extent_generation(leaf_l, ei_l) ==
6362 btrfs_file_extent_generation(leaf_r, ei_r) &&
6363 btrfs_file_extent_ram_bytes(leaf_l, ei_l) ==
6364 btrfs_file_extent_ram_bytes(leaf_r, ei_r) &&
6365 btrfs_file_extent_compression(leaf_l, ei_l) ==
6366 btrfs_file_extent_compression(leaf_r, ei_r) &&
6367 btrfs_file_extent_encryption(leaf_l, ei_l) ==
6368 btrfs_file_extent_encryption(leaf_r, ei_r) &&
6369 btrfs_file_extent_other_encoding(leaf_l, ei_l) ==
6370 btrfs_file_extent_other_encoding(leaf_r, ei_r) &&
6371 btrfs_file_extent_type(leaf_l, ei_l) ==
6372 btrfs_file_extent_type(leaf_r, ei_r) &&
6373 btrfs_file_extent_disk_bytenr(leaf_l, ei_l) !=
6374 btrfs_file_extent_disk_bytenr(leaf_r, ei_r) &&
6375 btrfs_file_extent_disk_num_bytes(leaf_l, ei_l) ==
6376 btrfs_file_extent_disk_num_bytes(leaf_r, ei_r) &&
6377 btrfs_file_extent_offset(leaf_l, ei_l) ==
6378 btrfs_file_extent_offset(leaf_r, ei_r) &&
6379 btrfs_file_extent_num_bytes(leaf_l, ei_l) ==
6380 btrfs_file_extent_num_bytes(leaf_r, ei_r))
6381 return 0;
6382 }
6383
6384 inconsistent_snapshot_error(sctx, result, "extent");
6385 return -EIO;
6386 }
6387 6340
6388 if (!sctx->cur_inode_new_gen && !sctx->cur_inode_deleted) { 6341 if (!sctx->cur_inode_new_gen && !sctx->cur_inode_deleted) {
6389 if (result != BTRFS_COMPARE_TREE_DELETED) 6342 if (result != BTRFS_COMPARE_TREE_DELETED)