btrfs: avoid unnecessary memory allocation and copy at overwrite_item()
authorFilipe Manana <fdmanana@suse.com>
Thu, 13 Mar 2025 14:00:52 +0000 (14:00 +0000)
committerDavid Sterba <dsterba@suse.com>
Tue, 18 Mar 2025 19:35:54 +0000 (20:35 +0100)
There's no need to allocate memory and copy from both the destination and
source extent buffers to compare if the items are equal, we can instead
use memcmp_extent_buffer() which allows to do only one memory allocation
and copy instead of two.

So use memcmp_extent_buffer() instead of memcmp(), allowing us to avoid
one memory allocation, which can fail or be slow while under memory heavy
pressure, avoid the memory copying and reducing code.

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/tree-log.c

index 2d23223f476b6a968cf7b3794b78ef63015907ea..91278cc83bd4a23d144cffe603c8afa246b41ff1 100644 (file)
@@ -422,7 +422,6 @@ static int overwrite_item(struct btrfs_trans_handle *trans,
 
        if (ret == 0) {
                char *src_copy;
-               char *dst_copy;
                u32 dst_size = btrfs_item_size(path->nodes[0],
                                                  path->slots[0]);
                if (dst_size != item_size)
@@ -432,23 +431,16 @@ static int overwrite_item(struct btrfs_trans_handle *trans,
                        btrfs_release_path(path);
                        return 0;
                }
-               dst_copy = kmalloc(item_size, GFP_NOFS);
                src_copy = kmalloc(item_size, GFP_NOFS);
-               if (!dst_copy || !src_copy) {
+               if (!src_copy) {
                        btrfs_release_path(path);
-                       kfree(dst_copy);
-                       kfree(src_copy);
                        return -ENOMEM;
                }
 
                read_extent_buffer(eb, src_copy, src_ptr, item_size);
-
                dst_ptr = btrfs_item_ptr_offset(path->nodes[0], path->slots[0]);
-               read_extent_buffer(path->nodes[0], dst_copy, dst_ptr,
-                                  item_size);
-               ret = memcmp(dst_copy, src_copy, item_size);
+               ret = memcmp_extent_buffer(path->nodes[0], src_copy, dst_ptr, item_size);
 
-               kfree(dst_copy);
                kfree(src_copy);
                /*
                 * they have the same contents, just return, this saves