aboutsummaryrefslogtreecommitdiffstats
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
commitf472d3c28385397b1a2891c4ec264b90cd6d2187 (patch)
tree0670f22721df5ebe4b0e121f400386afb963e615
parentbtrfs: optimize split page write in btrfs_set_##bits (diff)
downloadlinux-dev-f472d3c28385397b1a2891c4ec264b90cd6d2187.tar.xz
linux-dev-f472d3c28385397b1a2891c4ec264b90cd6d2187.zip
btrfs: optimize split page write in btrfs_set_token_##bits
The fallback path calls helper write_extent_buffer 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. The cached token address is set to the second page. Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> Signed-off-by: David Sterba <dsterba@suse.com>
-rw-r--r--fs/btrfs/struct-funcs.c12
1 files changed, 7 insertions, 5 deletions
diff --git a/fs/btrfs/struct-funcs.c b/fs/btrfs/struct-funcs.c
index 7987d3910660..225ef6d7e949 100644
--- a/fs/btrfs/struct-funcs.c
+++ b/fs/btrfs/struct-funcs.c
@@ -115,7 +115,8 @@ void btrfs_set_token_##bits(struct btrfs_map_token *token, \
const unsigned long idx = member_offset >> PAGE_SHIFT; \
const unsigned long oip = offset_in_page(member_offset); \
const int size = sizeof(u##bits); \
- __le##bits leres; \
+ u8 lebytes[sizeof(u##bits)]; \
+ const int part = PAGE_SIZE - oip; \
\
ASSERT(token); \
ASSERT(token->kaddr); \
@@ -125,16 +126,17 @@ void btrfs_set_token_##bits(struct btrfs_map_token *token, \
put_unaligned_le##bits(val, token->kaddr + oip); \
return; \
} \
+ token->kaddr = page_address(token->eb->pages[idx]); \
+ token->offset = idx << PAGE_SHIFT; \
if (oip + size <= PAGE_SIZE) { \
- token->kaddr = page_address(token->eb->pages[idx]); \
- token->offset = idx << PAGE_SHIFT; \
put_unaligned_le##bits(val, token->kaddr + oip); \
return; \
} \
+ put_unaligned_le##bits(val, lebytes); \
+ memcpy(token->kaddr + oip, lebytes, part); \
token->kaddr = page_address(token->eb->pages[idx + 1]); \
token->offset = (idx + 1) << PAGE_SHIFT; \
- leres = cpu_to_le##bits(val); \
- write_extent_buffer(token->eb, &leres, member_offset, size); \
+ memcpy(token->kaddr, lebytes + part, size - part); \
} \
void btrfs_set_##bits(const struct extent_buffer *eb, void *ptr, \
unsigned long off, u##bits val) \