diff options
author | David Sterba <dsterba@suse.com> | 2019-08-09 11:12:38 -0400 |
---|---|---|
committer | David Sterba <dsterba@suse.com> | 2019-09-09 08:59:16 -0400 |
commit | cb49511328dcce73840a54661622950d7fa6384e (patch) | |
tree | a380d0eb8fd8d8174502b0a415879765809e988b | |
parent | 6ff49c6ad285160b8ba48589ebdbf6cebdd42f74 (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.h | 15 | ||||
-rw-r--r-- | fs/btrfs/struct-funcs.c | 51 |
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, \ | |||
1335 | void btrfs_set_token_##bits(struct extent_buffer *eb, const void *ptr, \ | 1335 | void 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); \ |
1338 | static inline u##bits btrfs_get_##bits(const struct extent_buffer *eb, \ | 1338 | u##bits btrfs_get_##bits(const struct extent_buffer *eb, \ |
1339 | const void *ptr, \ | 1339 | const void *ptr, unsigned long off); \ |
1340 | unsigned long off) \ | 1340 | void 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 | } \ | ||
1344 | static 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 | ||
1350 | DECLARE_BTRFS_SETGET_BITS(8) | 1343 | DECLARE_BTRFS_SETGET_BITS(8) |
1351 | DECLARE_BTRFS_SETGET_BITS(16) | 1344 | DECLARE_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 | } \ |
80 | u##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 | } \ | ||
78 | void btrfs_set_token_##bits(struct extent_buffer *eb, \ | 105 | void 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 | } \ | ||
144 | void 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 | ||
118 | DEFINE_BTRFS_SETGET_BITS(8) | 169 | DEFINE_BTRFS_SETGET_BITS(8) |