btrfs: send: avoid unnecessary path allocations when finding extent clone

When looking for an extent clone, at find_extent_clone(), we start by
allocating a path and then check for cases where we can't have clones
and exit immediately in those cases. It's a waste of time to allocate
the path before those cases, so reorder the logic so that we check for
those cases before allocating the path.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
Filipe Manana 2022-11-01 16:15:41 +00:00 committed by David Sterba
parent 1a1a285139
commit 61ce908a3c

View file

@ -1365,40 +1365,35 @@ static int find_extent_clone(struct send_ctx *sctx,
int compressed; int compressed;
u32 i; u32 i;
tmp_path = alloc_path_for_send();
if (!tmp_path)
return -ENOMEM;
/* We only use this path under the commit sem */
tmp_path->need_commit_sem = 0;
if (data_offset >= ino_size) { if (data_offset >= ino_size) {
/* /*
* There may be extents that lie behind the file's size. * There may be extents that lie behind the file's size.
* I at least had this in combination with snapshotting while * I at least had this in combination with snapshotting while
* writing large files. * writing large files.
*/ */
ret = 0; return 0;
goto out;
} }
fi = btrfs_item_ptr(eb, path->slots[0], fi = btrfs_item_ptr(eb, path->slots[0], struct btrfs_file_extent_item);
struct btrfs_file_extent_item);
extent_type = btrfs_file_extent_type(eb, fi); extent_type = btrfs_file_extent_type(eb, fi);
if (extent_type == BTRFS_FILE_EXTENT_INLINE) { if (extent_type == BTRFS_FILE_EXTENT_INLINE)
ret = -ENOENT; return -ENOENT;
goto out;
}
compressed = btrfs_file_extent_compression(eb, fi);
num_bytes = btrfs_file_extent_num_bytes(eb, fi);
disk_byte = btrfs_file_extent_disk_bytenr(eb, fi); disk_byte = btrfs_file_extent_disk_bytenr(eb, fi);
if (disk_byte == 0) { if (disk_byte == 0)
ret = -ENOENT; return -ENOENT;
goto out;
} compressed = btrfs_file_extent_compression(eb, fi);
num_bytes = btrfs_file_extent_num_bytes(eb, fi);
logical = disk_byte + btrfs_file_extent_offset(eb, fi); logical = disk_byte + btrfs_file_extent_offset(eb, fi);
tmp_path = alloc_path_for_send();
if (!tmp_path)
return -ENOMEM;
/* We only use this path under the commit sem */
tmp_path->need_commit_sem = 0;
down_read(&fs_info->commit_root_sem); down_read(&fs_info->commit_root_sem);
ret = extent_from_logical(fs_info, disk_byte, tmp_path, ret = extent_from_logical(fs_info, disk_byte, tmp_path,
&found_key, &flags); &found_key, &flags);