summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Sterba <dsterba@suse.com>2020-04-30 17:57:55 +0200
committerDavid Sterba <dsterba@suse.com>2020-05-25 11:25:34 +0200
commitf4ca8c51d12631f1297d093f767c3a5ce5b95aff (patch)
tree6b46d01bde3761b1c903f95b1af9b49a2c95ac9b
parentba8a9a0537770df69d9dc38c11312c9b0f840cf2 (diff)
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: Johannes Thumshirn <johannes.thumshirn@wdc.com> Signed-off-by: David Sterba <dsterba@suse.com>
-rw-r--r--fs/btrfs/struct-funcs.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/fs/btrfs/struct-funcs.c b/fs/btrfs/struct-funcs.c
index 63cab91507f8..7987d3910660 100644
--- a/fs/btrfs/struct-funcs.c
+++ b/fs/btrfs/struct-funcs.c
@@ -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)