Commit e48264e6 authored by Filipe Manana's avatar Filipe Manana Committed by David Sterba
Browse files

btrfs: avoid unnecessary memory allocation and copy at overwrite_item()



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: default avatarFilipe Manana <fdmanana@suse.com>
Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent 9db9c7dd
Loading
Loading
Loading
Loading
+2 −10
Original line number Diff line number Diff line
@@ -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