Commit f4ca8c51 authored by David Sterba's avatar David Sterba
Browse files

btrfs: optimize split page write in btrfs_set_##bits



The helper write_extent_buffer is called to do write of the data
spanning two extent buffer pages. As the size is known, we can do the
write directly in two steps.  This removes one function call and
compiler can optimize memcpy as the sizes are known at compile time.

Reviewed-by: default avatarJohannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent ba8a9a05
Loading
Loading
Loading
Loading
+9 −5
Original line number Diff line number Diff line
@@ -141,18 +141,22 @@ void btrfs_set_##bits(const struct extent_buffer *eb, void *ptr, \
{									\
	const unsigned long member_offset = (unsigned long)ptr + off;	\
	const unsigned long oip = offset_in_page(member_offset);	\
	const unsigned long idx = member_offset >> PAGE_SHIFT;		\
	char *kaddr = page_address(eb->pages[idx]);			\
	const int size = sizeof(u##bits);				\
	__le##bits leres;						\
	const int part = PAGE_SIZE - oip;				\
	u8 lebytes[sizeof(u##bits)];					\
									\
	ASSERT(check_setget_bounds(eb, ptr, off, size));		\
	if (oip + size <= PAGE_SIZE) {					\
		const unsigned long idx = member_offset >> PAGE_SHIFT;	\
		char *kaddr = page_address(eb->pages[idx]);		\
		put_unaligned_le##bits(val, kaddr + oip);		\
		return;							\
	}								\
	leres = cpu_to_le##bits(val);					\
	write_extent_buffer(eb, &leres, member_offset, size);		\
									\
	put_unaligned_le##bits(val, lebytes);				\
	memcpy(kaddr + oip, lebytes, part);				\
	kaddr = page_address(eb->pages[idx + 1]);			\
	memcpy(kaddr, lebytes + part, size - part);			\
}

DEFINE_BTRFS_SETGET_BITS(8)