diff options
author | Chris Mason <chris.mason@oracle.com> | 2012-03-03 07:40:03 -0500 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2012-03-26 17:04:23 -0400 |
commit | cfed81a04eb555f5606d1b6a54bdbabab0ee1ac3 (patch) | |
tree | 2a763276869693b21c0e3a14f725f642c1f27fd3 /fs/btrfs/struct-funcs.c | |
parent | 0b32f4bbb423f02acee6d43cd442f5f0775db7e0 (diff) |
Btrfs: add the ability to cache a pointer into the eb
This cuts down on the CPU time used by map_private_extent_buffer
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/struct-funcs.c')
-rw-r--r-- | fs/btrfs/struct-funcs.c | 53 |
1 files changed, 46 insertions, 7 deletions
diff --git a/fs/btrfs/struct-funcs.c b/fs/btrfs/struct-funcs.c index bc1f6ad18442..c6ffa5812419 100644 --- a/fs/btrfs/struct-funcs.c +++ b/fs/btrfs/struct-funcs.c | |||
@@ -44,8 +44,9 @@ | |||
44 | #define BTRFS_SETGET_FUNCS(name, type, member, bits) \ | 44 | #define BTRFS_SETGET_FUNCS(name, type, member, bits) \ |
45 | u##bits btrfs_##name(struct extent_buffer *eb, type *s); \ | 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); \ | 46 | void btrfs_set_##name(struct extent_buffer *eb, type *s, u##bits val); \ |
47 | u##bits btrfs_##name(struct extent_buffer *eb, \ | 47 | void btrfs_set_token_##name(struct extent_buffer *eb, type *s, u##bits val, struct btrfs_map_token *token); \ |
48 | type *s) \ | 48 | u##bits btrfs_token_##name(struct extent_buffer *eb, \ |
49 | type *s, struct btrfs_map_token *token) \ | ||
49 | { \ | 50 | { \ |
50 | unsigned long part_offset = (unsigned long)s; \ | 51 | unsigned long part_offset = (unsigned long)s; \ |
51 | unsigned long offset = part_offset + offsetof(type, member); \ | 52 | unsigned long offset = part_offset + offsetof(type, member); \ |
@@ -54,9 +55,18 @@ u##bits btrfs_##name(struct extent_buffer *eb, \ | |||
54 | char *kaddr; \ | 55 | char *kaddr; \ |
55 | unsigned long map_start; \ | 56 | unsigned long map_start; \ |
56 | unsigned long map_len; \ | 57 | unsigned long map_len; \ |
58 | unsigned long mem_len = sizeof(((type *)0)->member); \ | ||
57 | u##bits res; \ | 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 | } \ | ||
58 | err = map_private_extent_buffer(eb, offset, \ | 68 | err = map_private_extent_buffer(eb, offset, \ |
59 | sizeof(((type *)0)->member), \ | 69 | mem_len, \ |
60 | &kaddr, &map_start, &map_len); \ | 70 | &kaddr, &map_start, &map_len); \ |
61 | if (err) { \ | 71 | if (err) { \ |
62 | __le##bits leres; \ | 72 | __le##bits leres; \ |
@@ -65,10 +75,15 @@ u##bits btrfs_##name(struct extent_buffer *eb, \ | |||
65 | } \ | 75 | } \ |
66 | p = (type *)(kaddr + part_offset - map_start); \ | 76 | p = (type *)(kaddr + part_offset - map_start); \ |
67 | res = le##bits##_to_cpu(p->member); \ | 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 | } \ | ||
68 | return res; \ | 83 | return res; \ |
69 | } \ | 84 | } \ |
70 | void btrfs_set_##name(struct extent_buffer *eb, \ | 85 | void btrfs_set_token_##name(struct extent_buffer *eb, \ |
71 | type *s, u##bits val) \ | 86 | type *s, u##bits val, struct btrfs_map_token *token) \ |
72 | { \ | 87 | { \ |
73 | unsigned long part_offset = (unsigned long)s; \ | 88 | unsigned long part_offset = (unsigned long)s; \ |
74 | unsigned long offset = part_offset + offsetof(type, member); \ | 89 | unsigned long offset = part_offset + offsetof(type, member); \ |
@@ -77,8 +92,17 @@ void btrfs_set_##name(struct extent_buffer *eb, \ | |||
77 | char *kaddr; \ | 92 | char *kaddr; \ |
78 | unsigned long map_start; \ | 93 | unsigned long map_start; \ |
79 | unsigned long map_len; \ | 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 | } \ | ||
80 | err = map_private_extent_buffer(eb, offset, \ | 104 | err = map_private_extent_buffer(eb, offset, \ |
81 | sizeof(((type *)0)->member), \ | 105 | mem_len, \ |
82 | &kaddr, &map_start, &map_len); \ | 106 | &kaddr, &map_start, &map_len); \ |
83 | if (err) { \ | 107 | if (err) { \ |
84 | __le##bits val2; \ | 108 | __le##bits val2; \ |
@@ -88,7 +112,22 @@ void btrfs_set_##name(struct extent_buffer *eb, \ | |||
88 | } \ | 112 | } \ |
89 | p = (type *)(kaddr + part_offset - map_start); \ | 113 | p = (type *)(kaddr + part_offset - map_start); \ |
90 | p->member = cpu_to_le##bits(val); \ | 114 | p->member = cpu_to_le##bits(val); \ |
91 | } | 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 | } \ | ||
92 | 131 | ||
93 | #include "ctree.h" | 132 | #include "ctree.h" |
94 | 133 | ||