OSDN Git Service

btrfs: send: avoid unnecessary path allocations when finding extent clone
authorFilipe Manana <fdmanana@suse.com>
Tue, 1 Nov 2022 16:15:41 +0000 (16:15 +0000)
committerDavid Sterba <dsterba@suse.com>
Mon, 5 Dec 2022 17:00:49 +0000 (18:00 +0100)
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>
fs/btrfs/send.c

index 3befc0d..d1388d5 100644 (file)
@@ -1365,40 +1365,35 @@ static int find_extent_clone(struct send_ctx *sctx,
        int compressed;
        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) {
                /*
                 * There may be extents that lie behind the file's size.
                 * I at least had this in combination with snapshotting while
                 * writing large files.
                 */
-               ret = 0;
-               goto out;
+               return 0;
        }
 
-       fi = btrfs_item_ptr(eb, path->slots[0],
-                       struct btrfs_file_extent_item);
+       fi = btrfs_item_ptr(eb, path->slots[0], struct btrfs_file_extent_item);
        extent_type = btrfs_file_extent_type(eb, fi);
-       if (extent_type == BTRFS_FILE_EXTENT_INLINE) {
-               ret = -ENOENT;
-               goto out;
-       }
-       compressed = btrfs_file_extent_compression(eb, fi);
+       if (extent_type == BTRFS_FILE_EXTENT_INLINE)
+               return -ENOENT;
 
-       num_bytes = btrfs_file_extent_num_bytes(eb, fi);
        disk_byte = btrfs_file_extent_disk_bytenr(eb, fi);
-       if (disk_byte == 0) {
-               ret = -ENOENT;
-               goto out;
-       }
+       if (disk_byte == 0)
+               return -ENOENT;
+
+       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);
 
+       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);
        ret = extent_from_logical(fs_info, disk_byte, tmp_path,
                                  &found_key, &flags);