summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Sterba <dsterba@suse.com>2019-08-09 11:12:38 -0400
committerDavid Sterba <dsterba@suse.com>2019-09-09 08:59:16 -0400
commitcb49511328dcce73840a54661622950d7fa6384e (patch)
treea380d0eb8fd8d8174502b0a415879765809e988b
parent6ff49c6ad285160b8ba48589ebdbf6cebdd42f74 (diff)
btrfs: define separate btrfs_set/get_XX helpers
There are helpers for all type widths defined via macro and optionally can use a token which is a cached pointer to avoid repeated mapping of the extent buffer. The token value is known at compile time, when it's valid it's always address of a local variable, otherwise it's NULL passed by the token-less helpers. This can be utilized to remove some branching as the helpers are used frequenlty. Signed-off-by: David Sterba <dsterba@suse.com>
-rw-r--r--fs/btrfs/ctree.h15
-rw-r--r--fs/btrfs/struct-funcs.c51
2 files changed, 55 insertions, 11 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 292e21b23217..8e18fb062215 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -1335,17 +1335,10 @@ u##bits btrfs_get_token_##bits(const struct extent_buffer *eb, \
1335void btrfs_set_token_##bits(struct extent_buffer *eb, const void *ptr, \ 1335void btrfs_set_token_##bits(struct extent_buffer *eb, const void *ptr, \
1336 unsigned long off, u##bits val, \ 1336 unsigned long off, u##bits val, \
1337 struct btrfs_map_token *token); \ 1337 struct btrfs_map_token *token); \
1338static inline u##bits btrfs_get_##bits(const struct extent_buffer *eb, \ 1338u##bits btrfs_get_##bits(const struct extent_buffer *eb, \
1339 const void *ptr, \ 1339 const void *ptr, unsigned long off); \
1340 unsigned long off) \ 1340void btrfs_set_##bits(struct extent_buffer *eb, void *ptr, \
1341{ \ 1341 unsigned long off, u##bits val);
1342 return btrfs_get_token_##bits(eb, ptr, off, NULL); \
1343} \
1344static inline void btrfs_set_##bits(struct extent_buffer *eb, void *ptr,\
1345 unsigned long off, u##bits val) \
1346{ \
1347 btrfs_set_token_##bits(eb, ptr, off, val, NULL); \
1348}
1349 1342
1350DECLARE_BTRFS_SETGET_BITS(8) 1343DECLARE_BTRFS_SETGET_BITS(8)
1351DECLARE_BTRFS_SETGET_BITS(16) 1344DECLARE_BTRFS_SETGET_BITS(16)
diff --git a/fs/btrfs/struct-funcs.c b/fs/btrfs/struct-funcs.c
index 4c13b737f568..e63936e4c1e0 100644
--- a/fs/btrfs/struct-funcs.c
+++ b/fs/btrfs/struct-funcs.c
@@ -33,6 +33,8 @@ static inline void put_unaligned_le8(u8 val, void *p)
33 * 33 *
34 * The extent buffer api is used to do the page spanning work required to 34 * The extent buffer api is used to do the page spanning work required to
35 * have a metadata blocksize different from the page size. 35 * have a metadata blocksize different from the page size.
36 *
37 * There are 2 variants defined, one with a token pointer and one without.
36 */ 38 */
37 39
38#define DEFINE_BTRFS_SETGET_BITS(bits) \ 40#define DEFINE_BTRFS_SETGET_BITS(bits) \
@@ -75,6 +77,31 @@ u##bits btrfs_get_token_##bits(const struct extent_buffer *eb, \
75 } \ 77 } \
76 return res; \ 78 return res; \
77} \ 79} \
80u##bits btrfs_get_##bits(const struct extent_buffer *eb, \
81 const void *ptr, unsigned long off) \
82{ \
83 unsigned long part_offset = (unsigned long)ptr; \
84 unsigned long offset = part_offset + off; \
85 void *p; \
86 int err; \
87 char *kaddr; \
88 unsigned long map_start; \
89 unsigned long map_len; \
90 int size = sizeof(u##bits); \
91 u##bits res; \
92 \
93 err = map_private_extent_buffer(eb, offset, size, \
94 &kaddr, &map_start, &map_len); \
95 if (err) { \
96 __le##bits leres; \
97 \
98 read_extent_buffer(eb, &leres, offset, size); \
99 return le##bits##_to_cpu(leres); \
100 } \
101 p = kaddr + part_offset - map_start; \
102 res = get_unaligned_le##bits(p + off); \
103 return res; \
104} \
78void btrfs_set_token_##bits(struct extent_buffer *eb, \ 105void btrfs_set_token_##bits(struct extent_buffer *eb, \
79 const void *ptr, unsigned long off, \ 106 const void *ptr, unsigned long off, \
80 u##bits val, \ 107 u##bits val, \
@@ -113,6 +140,30 @@ void btrfs_set_token_##bits(struct extent_buffer *eb, \
113 token->offset = map_start; \ 140 token->offset = map_start; \
114 token->eb = eb; \ 141 token->eb = eb; \
115 } \ 142 } \
143} \
144void btrfs_set_##bits(struct extent_buffer *eb, void *ptr, \
145 unsigned long off, u##bits val) \
146{ \
147 unsigned long part_offset = (unsigned long)ptr; \
148 unsigned long offset = part_offset + off; \
149 void *p; \
150 int err; \
151 char *kaddr; \
152 unsigned long map_start; \
153 unsigned long map_len; \
154 int size = sizeof(u##bits); \
155 \
156 err = map_private_extent_buffer(eb, offset, size, \
157 &kaddr, &map_start, &map_len); \
158 if (err) { \
159 __le##bits val2; \
160 \
161 val2 = cpu_to_le##bits(val); \
162 write_extent_buffer(eb, &val2, offset, size); \
163 return; \
164 } \
165 p = kaddr + part_offset - map_start; \
166 put_unaligned_le##bits(val, p + off); \
116} 167}
117 168
118DEFINE_BTRFS_SETGET_BITS(8) 169DEFINE_BTRFS_SETGET_BITS(8)