diff options
-rw-r--r-- | include/linux/sunrpc/cache.h | 113 |
1 files changed, 0 insertions, 113 deletions
diff --git a/include/linux/sunrpc/cache.h b/include/linux/sunrpc/cache.h index 3e17a5ff1dea..afc481dd02dd 100644 --- a/include/linux/sunrpc/cache.h +++ b/include/linux/sunrpc/cache.h | |||
@@ -128,119 +128,6 @@ struct cache_deferred_req { | |||
128 | int too_many); | 128 | int too_many); |
129 | }; | 129 | }; |
130 | 130 | ||
131 | /* | ||
132 | * just like a template in C++, this macro does cache lookup | ||
133 | * for us. | ||
134 | * The function is passed some sort of HANDLE from which a cache_detail | ||
135 | * structure can be determined (via SETUP, DETAIL), a template | ||
136 | * cache entry (type RTN*), and a "set" flag. Using the HASHFN and the | ||
137 | * TEST, the function will try to find a matching cache entry in the cache. | ||
138 | * If "set" == 0 : | ||
139 | * If an entry is found, it is returned | ||
140 | * If no entry is found, a new non-VALID entry is created. | ||
141 | * If "set" == 1 : | ||
142 | * If no entry is found a new one is inserted with data from "template" | ||
143 | * If a non-CACHE_VALID entry is found, it is updated from template using UPDATE | ||
144 | * If a CACHE_VALID entry is found, a new entry is swapped in with data | ||
145 | * from "template" | ||
146 | * | ||
147 | * If the passed handle has the CACHE_NEGATIVE flag set, then UPDATE is not | ||
148 | * run but insteead CACHE_NEGATIVE is set in any new item. | ||
149 | |||
150 | * In any case, the new entry is returned with a reference count. | ||
151 | * | ||
152 | * | ||
153 | * RTN is a struct type for a cache entry | ||
154 | * MEMBER is the member of the cache which is cache_head, which must be first | ||
155 | * FNAME is the name for the function | ||
156 | * ARGS are arguments to function and must contain RTN *item, int set. May | ||
157 | * also contain something to be usedby SETUP or DETAIL to find cache_detail. | ||
158 | * SETUP locates the cache detail and makes it available as... | ||
159 | * DETAIL identifies the cache detail, possibly set up by SETUP | ||
160 | * HASHFN returns a hash value of the cache entry "item" | ||
161 | * TEST tests if "tmp" matches "item" | ||
162 | * INIT copies key information from "item" to "new" | ||
163 | * UPDATE copies content information from "item" to "tmp" | ||
164 | */ | ||
165 | #define DefineCacheLookup(RTN,MEMBER,FNAME,ARGS,SETUP,DETAIL,HASHFN,TEST,INIT,UPDATE) \ | ||
166 | RTN *FNAME ARGS \ | ||
167 | { \ | ||
168 | RTN *tmp, *new=NULL; \ | ||
169 | struct cache_head **hp, **head; \ | ||
170 | SETUP; \ | ||
171 | head = &(DETAIL)->hash_table[HASHFN]; \ | ||
172 | retry: \ | ||
173 | if (set||new) write_lock(&(DETAIL)->hash_lock); \ | ||
174 | else read_lock(&(DETAIL)->hash_lock); \ | ||
175 | for(hp=head; *hp != NULL; hp = &tmp->MEMBER.next) { \ | ||
176 | tmp = container_of(*hp, RTN, MEMBER); \ | ||
177 | if (TEST) { /* found a match */ \ | ||
178 | \ | ||
179 | if (set && test_bit(CACHE_VALID, &tmp->MEMBER.flags) && !new) \ | ||
180 | break; \ | ||
181 | \ | ||
182 | if (new) \ | ||
183 | {INIT;} \ | ||
184 | if (set) { \ | ||
185 | if (test_bit(CACHE_VALID, &tmp->MEMBER.flags))\ | ||
186 | { /* need to swap in new */ \ | ||
187 | RTN *t2; \ | ||
188 | \ | ||
189 | new->MEMBER.next = tmp->MEMBER.next; \ | ||
190 | *hp = &new->MEMBER; \ | ||
191 | tmp->MEMBER.next = NULL; \ | ||
192 | t2 = tmp; tmp = new; new = t2; \ | ||
193 | } \ | ||
194 | if (test_bit(CACHE_NEGATIVE, &item->MEMBER.flags)) \ | ||
195 | set_bit(CACHE_NEGATIVE, &tmp->MEMBER.flags); \ | ||
196 | else { \ | ||
197 | UPDATE; \ | ||
198 | clear_bit(CACHE_NEGATIVE, &tmp->MEMBER.flags); \ | ||
199 | } \ | ||
200 | } \ | ||
201 | cache_get(&tmp->MEMBER); \ | ||
202 | if (set||new) write_unlock(&(DETAIL)->hash_lock); \ | ||
203 | else read_unlock(&(DETAIL)->hash_lock); \ | ||
204 | if (set) \ | ||
205 | cache_fresh(DETAIL, &tmp->MEMBER, item->MEMBER.expiry_time); \ | ||
206 | if (set && new) cache_fresh(DETAIL, &new->MEMBER, 0); \ | ||
207 | if (new) (DETAIL)->cache_put(&new->MEMBER, DETAIL); \ | ||
208 | return tmp; \ | ||
209 | } \ | ||
210 | } \ | ||
211 | /* Didn't find anything */ \ | ||
212 | if (new) { \ | ||
213 | INIT; \ | ||
214 | new->MEMBER.next = *head; \ | ||
215 | *head = &new->MEMBER; \ | ||
216 | (DETAIL)->entries ++; \ | ||
217 | cache_get(&new->MEMBER); \ | ||
218 | if (set) { \ | ||
219 | tmp = new; \ | ||
220 | if (test_bit(CACHE_NEGATIVE, &item->MEMBER.flags)) \ | ||
221 | set_bit(CACHE_NEGATIVE, &tmp->MEMBER.flags); \ | ||
222 | else {UPDATE;} \ | ||
223 | } \ | ||
224 | } \ | ||
225 | if (set||new) write_unlock(&(DETAIL)->hash_lock); \ | ||
226 | else read_unlock(&(DETAIL)->hash_lock); \ | ||
227 | if (new && set) \ | ||
228 | cache_fresh(DETAIL, &new->MEMBER, item->MEMBER.expiry_time); \ | ||
229 | if (new) \ | ||
230 | return new; \ | ||
231 | new = kmalloc(sizeof(*new), GFP_KERNEL); \ | ||
232 | if (new) { \ | ||
233 | cache_init(&new->MEMBER); \ | ||
234 | goto retry; \ | ||
235 | } \ | ||
236 | return NULL; \ | ||
237 | } | ||
238 | |||
239 | #define DefineSimpleCacheLookup(STRUCT, FUNC) \ | ||
240 | DefineCacheLookup(struct STRUCT, h, FUNC##_lookup, \ | ||
241 | (struct STRUCT *item, int set), /*no setup */, \ | ||
242 | & FUNC##_cache, FUNC##_hash(item), FUNC##_match(item, tmp), \ | ||
243 | STRUCT##_init(new, item), STRUCT##_update(tmp, item)) | ||
244 | 131 | ||
245 | extern struct cache_head * | 132 | extern struct cache_head * |
246 | sunrpc_cache_lookup(struct cache_detail *detail, | 133 | sunrpc_cache_lookup(struct cache_detail *detail, |