diff options
Diffstat (limited to 'fs/btrfs/send.c')
-rw-r--r-- | fs/btrfs/send.c | 77 |
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) |