Commit 18077bb413687f96bd168efcfb2b8778529e3b74
Committed by
Chris Mason
1 parent
293f7e0740
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
Btrfs: rewrite BTRFS_SETGET_FUNCS
BTRFS_SETGET_FUNCS macro is used to generate btrfs_set_foo() and btrfs_foo() functions, which read and write specific fields in the extent buffer. The total number of set/get functions is ~200, but in fact we only need 8 functions: 2 for u8 field, 2 for u16, 2 for u32 and 2 for u64. It results in redunction of ~37K bytes. text data bss dec hex filename 629661 12489 216 642366 9cd3e fs/btrfs/btrfs.o.orig 592637 12489 216 605342 93c9e fs/btrfs/btrfs.o Signed-off-by: Li Zefan <lizefan@huawei.com>
Showing 2 changed files with 146 additions and 103 deletions Side-by-side Diff
fs/btrfs/ctree.h
... | ... | @@ -1623,13 +1623,54 @@ |
1623 | 1623 | offsetof(type, member), \ |
1624 | 1624 | sizeof(((type *)0)->member))) |
1625 | 1625 | |
1626 | -#ifndef BTRFS_SETGET_FUNCS | |
1626 | +#define DECLARE_BTRFS_SETGET_BITS(bits) \ | |
1627 | +u##bits btrfs_get_token_##bits(struct extent_buffer *eb, void *ptr, \ | |
1628 | + unsigned long off, \ | |
1629 | + struct btrfs_map_token *token); \ | |
1630 | +void btrfs_set_token_##bits(struct extent_buffer *eb, void *ptr, \ | |
1631 | + unsigned long off, u##bits val, \ | |
1632 | + struct btrfs_map_token *token); \ | |
1633 | +static inline u##bits btrfs_get_##bits(struct extent_buffer *eb, void *ptr, \ | |
1634 | + unsigned long off) \ | |
1635 | +{ \ | |
1636 | + return btrfs_get_token_##bits(eb, ptr, off, NULL); \ | |
1637 | +} \ | |
1638 | +static inline void btrfs_set_##bits(struct extent_buffer *eb, void *ptr, \ | |
1639 | + unsigned long off, u##bits val) \ | |
1640 | +{ \ | |
1641 | + btrfs_set_token_##bits(eb, ptr, off, val, NULL); \ | |
1642 | +} | |
1643 | + | |
1644 | +DECLARE_BTRFS_SETGET_BITS(8) | |
1645 | +DECLARE_BTRFS_SETGET_BITS(16) | |
1646 | +DECLARE_BTRFS_SETGET_BITS(32) | |
1647 | +DECLARE_BTRFS_SETGET_BITS(64) | |
1648 | + | |
1627 | 1649 | #define BTRFS_SETGET_FUNCS(name, type, member, bits) \ |
1628 | -u##bits btrfs_##name(struct extent_buffer *eb, type *s); \ | |
1629 | -u##bits btrfs_token_##name(struct extent_buffer *eb, type *s, struct btrfs_map_token *token); \ | |
1630 | -void btrfs_set_token_##name(struct extent_buffer *eb, type *s, u##bits val, struct btrfs_map_token *token);\ | |
1631 | -void btrfs_set_##name(struct extent_buffer *eb, type *s, u##bits val); | |
1632 | -#endif | |
1650 | +static inline u##bits btrfs_##name(struct extent_buffer *eb, type *s) \ | |
1651 | +{ \ | |
1652 | + BUILD_BUG_ON(sizeof(u##bits) != sizeof(((type *)0))->member); \ | |
1653 | + return btrfs_get_##bits(eb, s, offsetof(type, member)); \ | |
1654 | +} \ | |
1655 | +static inline void btrfs_set_##name(struct extent_buffer *eb, type *s, \ | |
1656 | + u##bits val) \ | |
1657 | +{ \ | |
1658 | + BUILD_BUG_ON(sizeof(u##bits) != sizeof(((type *)0))->member); \ | |
1659 | + btrfs_set_##bits(eb, s, offsetof(type, member), val); \ | |
1660 | +} \ | |
1661 | +static inline u##bits btrfs_token_##name(struct extent_buffer *eb, type *s, \ | |
1662 | + struct btrfs_map_token *token) \ | |
1663 | +{ \ | |
1664 | + BUILD_BUG_ON(sizeof(u##bits) != sizeof(((type *)0))->member); \ | |
1665 | + return btrfs_get_token_##bits(eb, s, offsetof(type, member), token); \ | |
1666 | +} \ | |
1667 | +static inline void btrfs_set_token_##name(struct extent_buffer *eb, \ | |
1668 | + type *s, u##bits val, \ | |
1669 | + struct btrfs_map_token *token) \ | |
1670 | +{ \ | |
1671 | + BUILD_BUG_ON(sizeof(u##bits) != sizeof(((type *)0))->member); \ | |
1672 | + btrfs_set_token_##bits(eb, s, offsetof(type, member), val, token); \ | |
1673 | +} | |
1633 | 1674 | |
1634 | 1675 | #define BTRFS_SETGET_HEADER_FUNCS(name, type, member, bits) \ |
1635 | 1676 | static inline u##bits btrfs_##name(struct extent_buffer *eb) \ |
fs/btrfs/struct-funcs.c
... | ... | @@ -17,119 +17,121 @@ |
17 | 17 | */ |
18 | 18 | |
19 | 19 | #include <linux/highmem.h> |
20 | +#include <asm/unaligned.h> | |
20 | 21 | |
21 | -/* this is some deeply nasty code. ctree.h has a different | |
22 | - * definition for this BTRFS_SETGET_FUNCS macro, behind a #ifndef | |
22 | +#include "ctree.h" | |
23 | + | |
24 | +static inline u8 get_unaligned_le8(const void *p) | |
25 | +{ | |
26 | + return *(u8 *)p; | |
27 | +} | |
28 | + | |
29 | +static inline void put_unaligned_le8(u8 val, void *p) | |
30 | +{ | |
31 | + *(u8 *)p = val; | |
32 | +} | |
33 | + | |
34 | +/* | |
35 | + * this is some deeply nasty code. | |
23 | 36 | * |
24 | 37 | * The end result is that anyone who #includes ctree.h gets a |
25 | - * declaration for the btrfs_set_foo functions and btrfs_foo functions | |
38 | + * declaration for the btrfs_set_foo functions and btrfs_foo functions, | |
39 | + * which are wappers of btrfs_set_token_#bits functions and | |
40 | + * btrfs_get_token_#bits functions, which are defined in this file. | |
26 | 41 | * |
27 | - * This file declares the macros and then #includes ctree.h, which results | |
28 | - * in cpp creating the function here based on the template below. | |
29 | - * | |
30 | 42 | * These setget functions do all the extent_buffer related mapping |
31 | 43 | * required to efficiently read and write specific fields in the extent |
32 | 44 | * buffers. Every pointer to metadata items in btrfs is really just |
33 | 45 | * an unsigned long offset into the extent buffer which has been |
34 | 46 | * cast to a specific type. This gives us all the gcc type checking. |
35 | 47 | * |
36 | - * The extent buffer api is used to do all the kmapping and page | |
37 | - * spanning work required to get extent buffers in highmem and have | |
38 | - * a metadata blocksize different from the page size. | |
39 | - * | |
40 | - * The macro starts with a simple function prototype declaration so that | |
41 | - * sparse won't complain about it being static. | |
48 | + * The extent buffer api is used to do the page spanning work required to | |
49 | + * have a metadata blocksize different from the page size. | |
42 | 50 | */ |
43 | 51 | |
44 | -#define BTRFS_SETGET_FUNCS(name, type, member, bits) \ | |
45 | -u##bits btrfs_##name(struct extent_buffer *eb, type *s); \ | |
46 | -void btrfs_set_##name(struct extent_buffer *eb, type *s, u##bits val); \ | |
47 | -void btrfs_set_token_##name(struct extent_buffer *eb, type *s, u##bits val, struct btrfs_map_token *token); \ | |
48 | -u##bits btrfs_token_##name(struct extent_buffer *eb, \ | |
49 | - type *s, struct btrfs_map_token *token) \ | |
52 | +#define DEFINE_BTRFS_SETGET_BITS(bits) \ | |
53 | +u##bits btrfs_get_token_##bits(struct extent_buffer *eb, void *ptr, \ | |
54 | + unsigned long off, \ | |
55 | + struct btrfs_map_token *token) \ | |
50 | 56 | { \ |
51 | - unsigned long part_offset = (unsigned long)s; \ | |
52 | - unsigned long offset = part_offset + offsetof(type, member); \ | |
53 | - type *p; \ | |
54 | - int err; \ | |
55 | - char *kaddr; \ | |
56 | - unsigned long map_start; \ | |
57 | - unsigned long map_len; \ | |
58 | - unsigned long mem_len = sizeof(((type *)0)->member); \ | |
59 | - u##bits res; \ | |
60 | - if (token && token->kaddr && token->offset <= offset && \ | |
61 | - token->eb == eb && \ | |
62 | - (token->offset + PAGE_CACHE_SIZE >= offset + mem_len)) { \ | |
63 | - kaddr = token->kaddr; \ | |
64 | - p = (type *)(kaddr + part_offset - token->offset); \ | |
65 | - res = le##bits##_to_cpu(p->member); \ | |
66 | - return res; \ | |
67 | - } \ | |
68 | - err = map_private_extent_buffer(eb, offset, \ | |
69 | - mem_len, \ | |
70 | - &kaddr, &map_start, &map_len); \ | |
71 | - if (err) { \ | |
72 | - __le##bits leres; \ | |
73 | - read_eb_member(eb, s, type, member, &leres); \ | |
74 | - return le##bits##_to_cpu(leres); \ | |
75 | - } \ | |
76 | - p = (type *)(kaddr + part_offset - map_start); \ | |
77 | - res = le##bits##_to_cpu(p->member); \ | |
78 | - if (token) { \ | |
79 | - token->kaddr = kaddr; \ | |
80 | - token->offset = map_start; \ | |
81 | - token->eb = eb; \ | |
82 | - } \ | |
83 | - return res; \ | |
57 | + unsigned long part_offset = (unsigned long)ptr; \ | |
58 | + unsigned long offset = part_offset + off; \ | |
59 | + void *p; \ | |
60 | + int err; \ | |
61 | + char *kaddr; \ | |
62 | + unsigned long map_start; \ | |
63 | + unsigned long map_len; \ | |
64 | + int size = sizeof(u##bits); \ | |
65 | + u##bits res; \ | |
66 | + \ | |
67 | + if (token && token->kaddr && token->offset <= offset && \ | |
68 | + token->eb == eb && \ | |
69 | + (token->offset + PAGE_CACHE_SIZE >= offset + size)) { \ | |
70 | + kaddr = token->kaddr; \ | |
71 | + p = kaddr + part_offset - token->offset; \ | |
72 | + res = get_unaligned_le##bits(p + off); \ | |
73 | + return res; \ | |
74 | + } \ | |
75 | + err = map_private_extent_buffer(eb, offset, size, \ | |
76 | + &kaddr, &map_start, &map_len); \ | |
77 | + if (err) { \ | |
78 | + __le##bits leres; \ | |
79 | + \ | |
80 | + read_extent_buffer(eb, &leres, offset, size); \ | |
81 | + return le##bits##_to_cpu(leres); \ | |
82 | + } \ | |
83 | + p = kaddr + part_offset - map_start; \ | |
84 | + res = get_unaligned_le##bits(p + off); \ | |
85 | + if (token) { \ | |
86 | + token->kaddr = kaddr; \ | |
87 | + token->offset = map_start; \ | |
88 | + token->eb = eb; \ | |
89 | + } \ | |
90 | + return res; \ | |
84 | 91 | } \ |
85 | -void btrfs_set_token_##name(struct extent_buffer *eb, \ | |
86 | - type *s, u##bits val, struct btrfs_map_token *token) \ | |
92 | +void btrfs_set_token_##bits(struct extent_buffer *eb, \ | |
93 | + void *ptr, unsigned long off, u##bits val, \ | |
94 | + struct btrfs_map_token *token) \ | |
87 | 95 | { \ |
88 | - unsigned long part_offset = (unsigned long)s; \ | |
89 | - unsigned long offset = part_offset + offsetof(type, member); \ | |
90 | - type *p; \ | |
91 | - int err; \ | |
92 | - char *kaddr; \ | |
93 | - unsigned long map_start; \ | |
94 | - unsigned long map_len; \ | |
95 | - unsigned long mem_len = sizeof(((type *)0)->member); \ | |
96 | - if (token && token->kaddr && token->offset <= offset && \ | |
97 | - token->eb == eb && \ | |
98 | - (token->offset + PAGE_CACHE_SIZE >= offset + mem_len)) { \ | |
99 | - kaddr = token->kaddr; \ | |
100 | - p = (type *)(kaddr + part_offset - token->offset); \ | |
101 | - p->member = cpu_to_le##bits(val); \ | |
102 | - return; \ | |
103 | - } \ | |
104 | - err = map_private_extent_buffer(eb, offset, \ | |
105 | - mem_len, \ | |
106 | - &kaddr, &map_start, &map_len); \ | |
107 | - if (err) { \ | |
108 | - __le##bits val2; \ | |
109 | - val2 = cpu_to_le##bits(val); \ | |
110 | - write_eb_member(eb, s, type, member, &val2); \ | |
111 | - return; \ | |
112 | - } \ | |
113 | - p = (type *)(kaddr + part_offset - map_start); \ | |
114 | - p->member = cpu_to_le##bits(val); \ | |
115 | - if (token) { \ | |
116 | - token->kaddr = kaddr; \ | |
117 | - token->offset = map_start; \ | |
118 | - token->eb = eb; \ | |
119 | - } \ | |
120 | -} \ | |
121 | -void btrfs_set_##name(struct extent_buffer *eb, \ | |
122 | - type *s, u##bits val) \ | |
123 | -{ \ | |
124 | - btrfs_set_token_##name(eb, s, val, NULL); \ | |
125 | -} \ | |
126 | -u##bits btrfs_##name(struct extent_buffer *eb, \ | |
127 | - type *s) \ | |
128 | -{ \ | |
129 | - return btrfs_token_##name(eb, s, NULL); \ | |
130 | -} \ | |
96 | + unsigned long part_offset = (unsigned long)ptr; \ | |
97 | + unsigned long offset = part_offset + off; \ | |
98 | + void *p; \ | |
99 | + int err; \ | |
100 | + char *kaddr; \ | |
101 | + unsigned long map_start; \ | |
102 | + unsigned long map_len; \ | |
103 | + int size = sizeof(u##bits); \ | |
104 | + \ | |
105 | + if (token && token->kaddr && token->offset <= offset && \ | |
106 | + token->eb == eb && \ | |
107 | + (token->offset + PAGE_CACHE_SIZE >= offset + size)) { \ | |
108 | + kaddr = token->kaddr; \ | |
109 | + p = kaddr + part_offset - token->offset; \ | |
110 | + put_unaligned_le##bits(val, p + off); \ | |
111 | + return; \ | |
112 | + } \ | |
113 | + err = map_private_extent_buffer(eb, offset, size, \ | |
114 | + &kaddr, &map_start, &map_len); \ | |
115 | + if (err) { \ | |
116 | + __le##bits val2; \ | |
117 | + \ | |
118 | + val2 = cpu_to_le##bits(val); \ | |
119 | + write_extent_buffer(eb, &val2, offset, size); \ | |
120 | + return; \ | |
121 | + } \ | |
122 | + p = kaddr + part_offset - map_start; \ | |
123 | + put_unaligned_le##bits(val, p + off); \ | |
124 | + if (token) { \ | |
125 | + token->kaddr = kaddr; \ | |
126 | + token->offset = map_start; \ | |
127 | + token->eb = eb; \ | |
128 | + } \ | |
129 | +} | |
131 | 130 | |
132 | -#include "ctree.h" | |
131 | +DEFINE_BTRFS_SETGET_BITS(8) | |
132 | +DEFINE_BTRFS_SETGET_BITS(16) | |
133 | +DEFINE_BTRFS_SETGET_BITS(32) | |
134 | +DEFINE_BTRFS_SETGET_BITS(64) | |
133 | 135 | |
134 | 136 | void btrfs_node_key(struct extent_buffer *eb, |
135 | 137 | struct btrfs_disk_key *disk_key, int nr) |