btrfs: send: use btrfs_file_extent_end() in send_write_or_clone()
authorOmar Sandoval <osandov@fb.com>
Fri, 21 Aug 2020 07:39:53 +0000 (00:39 -0700)
committerDavid Sterba <dsterba@suse.com>
Wed, 7 Oct 2020 10:13:17 +0000 (12:13 +0200)
send_write_or_clone() basically has an open-coded copy of
btrfs_file_extent_end() except that it (incorrectly) aligns to PAGE_SIZE
instead of sectorsize. Fix and simplify the code by using
btrfs_file_extent_end().

Reviewed-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: Omar Sandoval <osandov@fb.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/send.c

index 491c486..ac0e942 100644 (file)
@@ -5400,51 +5400,29 @@ static int send_write_or_clone(struct send_ctx *sctx,
                               struct clone_root *clone_root)
 {
        int ret = 0;
-       struct btrfs_file_extent_item *ei;
        u64 offset = key->offset;
-       u64 len;
-       u8 type;
+       u64 end;
        u64 bs = sctx->send_root->fs_info->sb->s_blocksize;
 
-       ei = btrfs_item_ptr(path->nodes[0], path->slots[0],
-                       struct btrfs_file_extent_item);
-       type = btrfs_file_extent_type(path->nodes[0], ei);
-       if (type == BTRFS_FILE_EXTENT_INLINE) {
-               len = btrfs_file_extent_ram_bytes(path->nodes[0], ei);
-               /*
-                * it is possible the inline item won't cover the whole page,
-                * but there may be items after this page.  Make
-                * sure to send the whole thing
-                */
-               len = PAGE_ALIGN(len);
-       } else {
-               len = btrfs_file_extent_num_bytes(path->nodes[0], ei);
-       }
-
-       if (offset >= sctx->cur_inode_size) {
-               ret = 0;
-               goto out;
-       }
-       if (offset + len > sctx->cur_inode_size)
-               len = sctx->cur_inode_size - offset;
-       if (len == 0) {
-               ret = 0;
-               goto out;
-       }
+       end = min_t(u64, btrfs_file_extent_end(path), sctx->cur_inode_size);
+       if (offset >= end)
+               return 0;
 
-       if (clone_root && IS_ALIGNED(offset + len, bs)) {
+       if (clone_root && IS_ALIGNED(end, bs)) {
+               struct btrfs_file_extent_item *ei;
                u64 disk_byte;
                u64 data_offset;
 
+               ei = btrfs_item_ptr(path->nodes[0], path->slots[0],
+                                   struct btrfs_file_extent_item);
                disk_byte = btrfs_file_extent_disk_bytenr(path->nodes[0], ei);
                data_offset = btrfs_file_extent_offset(path->nodes[0], ei);
                ret = clone_range(sctx, clone_root, disk_byte, data_offset,
-                                 offset, len);
+                                 offset, end - offset);
        } else {
-               ret = send_extent_data(sctx, offset, len);
+               ret = send_extent_data(sctx, offset, end - offset);
        }
-       sctx->cur_inode_next_write_offset = offset + len;
-out:
+       sctx->cur_inode_next_write_offset = end;
        return ret;
 }