]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
btrfs: send: do not allocate memory for xattr data when checking it exists
authorFilipe Manana <fdmanana@suse.com>
Wed, 19 Nov 2025 17:59:52 +0000 (17:59 +0000)
committerDavid Sterba <dsterba@suse.com>
Tue, 25 Nov 2025 00:53:33 +0000 (01:53 +0100)
When checking if xattrs were deleted we don't care about their data, but
we are allocating memory for the data and copying it, which only wastes
time and can result in an unnecessary error in case the allocation fails.
So stop allocating memory and copying data by making find_xattr() and
__find_xattr() skip those steps if the given data buffer is NULL.

Reviewed-by: Boris Burkov <boris@bur.io>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/send.c

index 9da559f79f7f16a58f4d620d7af8b58e2966ad57..130aabced2074f82bfd7d2bccb1f9dea7656ef86 100644 (file)
@@ -4943,6 +4943,7 @@ struct find_xattr_ctx {
        int found_idx;
        char *found_data;
        int found_data_len;
+       bool copy_data;
 };
 
 static int __find_xattr(int num, struct btrfs_key *di_key, const char *name,
@@ -4954,9 +4955,11 @@ static int __find_xattr(int num, struct btrfs_key *di_key, const char *name,
            strncmp(name, ctx->name, name_len) == 0) {
                ctx->found_idx = num;
                ctx->found_data_len = data_len;
-               ctx->found_data = kmemdup(data, data_len, GFP_KERNEL);
-               if (!ctx->found_data)
-                       return -ENOMEM;
+               if (ctx->copy_data) {
+                       ctx->found_data = kmemdup(data, data_len, GFP_KERNEL);
+                       if (!ctx->found_data)
+                               return -ENOMEM;
+               }
                return 1;
        }
        return 0;
@@ -4976,6 +4979,7 @@ static int find_xattr(struct btrfs_root *root,
        ctx.found_idx = -1;
        ctx.found_data = NULL;
        ctx.found_data_len = 0;
+       ctx.copy_data = (data != NULL);
 
        ret = iterate_dir_item(root, path, __find_xattr, &ctx);
        if (ret < 0)
@@ -4987,7 +4991,7 @@ static int find_xattr(struct btrfs_root *root,
                *data = ctx.found_data;
                *data_len = ctx.found_data_len;
        } else {
-               kfree(ctx.found_data);
+               ASSERT(ctx.found_data == NULL);
        }
        return ctx.found_idx;
 }