diff options
Diffstat (limited to 'fs/nfsd')
-rw-r--r-- | fs/nfsd/export.c | 368 | ||||
-rw-r--r-- | fs/nfsd/nfs4idmap.c | 146 | ||||
-rw-r--r-- | fs/nfsd/nfsctl.c | 4 | ||||
-rw-r--r-- | fs/nfsd/nfsfh.c | 2 | ||||
-rw-r--r-- | fs/nfsd/stats.c | 2 | ||||
-rw-r--r-- | fs/nfsd/vfs.c | 2 |
6 files changed, 364 insertions, 160 deletions
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c index 417ec02df44f..c340be0a3f59 100644 --- a/fs/nfsd/export.c +++ b/fs/nfsd/export.c | |||
@@ -57,27 +57,17 @@ static int exp_verify_string(char *cp, int max); | |||
57 | #define EXPKEY_HASHMASK (EXPKEY_HASHMAX -1) | 57 | #define EXPKEY_HASHMASK (EXPKEY_HASHMAX -1) |
58 | static struct cache_head *expkey_table[EXPKEY_HASHMAX]; | 58 | static struct cache_head *expkey_table[EXPKEY_HASHMAX]; |
59 | 59 | ||
60 | static inline int svc_expkey_hash(struct svc_expkey *item) | 60 | static void expkey_put(struct kref *ref) |
61 | { | 61 | { |
62 | int hash = item->ek_fsidtype; | 62 | struct svc_expkey *key = container_of(ref, struct svc_expkey, h.ref); |
63 | char * cp = (char*)item->ek_fsid; | ||
64 | int len = key_len(item->ek_fsidtype); | ||
65 | 63 | ||
66 | hash ^= hash_mem(cp, len, EXPKEY_HASHBITS); | 64 | if (test_bit(CACHE_VALID, &key->h.flags) && |
67 | hash ^= hash_ptr(item->ek_client, EXPKEY_HASHBITS); | 65 | !test_bit(CACHE_NEGATIVE, &key->h.flags)) { |
68 | return hash & EXPKEY_HASHMASK; | 66 | dput(key->ek_dentry); |
69 | } | 67 | mntput(key->ek_mnt); |
70 | |||
71 | void expkey_put(struct cache_head *item, struct cache_detail *cd) | ||
72 | { | ||
73 | if (cache_put(item, cd)) { | ||
74 | struct svc_expkey *key = container_of(item, struct svc_expkey, h); | ||
75 | if (test_bit(CACHE_VALID, &item->flags) && | ||
76 | !test_bit(CACHE_NEGATIVE, &item->flags)) | ||
77 | exp_put(key->ek_export); | ||
78 | auth_domain_put(key->ek_client); | ||
79 | kfree(key); | ||
80 | } | 68 | } |
69 | auth_domain_put(key->ek_client); | ||
70 | kfree(key); | ||
81 | } | 71 | } |
82 | 72 | ||
83 | static void expkey_request(struct cache_detail *cd, | 73 | static void expkey_request(struct cache_detail *cd, |
@@ -95,7 +85,10 @@ static void expkey_request(struct cache_detail *cd, | |||
95 | (*bpp)[-1] = '\n'; | 85 | (*bpp)[-1] = '\n'; |
96 | } | 86 | } |
97 | 87 | ||
98 | static struct svc_expkey *svc_expkey_lookup(struct svc_expkey *, int); | 88 | static struct svc_expkey *svc_expkey_update(struct svc_expkey *new, struct svc_expkey *old); |
89 | static struct svc_expkey *svc_expkey_lookup(struct svc_expkey *); | ||
90 | static struct cache_detail svc_expkey_cache; | ||
91 | |||
99 | static int expkey_parse(struct cache_detail *cd, char *mesg, int mlen) | 92 | static int expkey_parse(struct cache_detail *cd, char *mesg, int mlen) |
100 | { | 93 | { |
101 | /* client fsidtype fsid [path] */ | 94 | /* client fsidtype fsid [path] */ |
@@ -106,6 +99,7 @@ static int expkey_parse(struct cache_detail *cd, char *mesg, int mlen) | |||
106 | int fsidtype; | 99 | int fsidtype; |
107 | char *ep; | 100 | char *ep; |
108 | struct svc_expkey key; | 101 | struct svc_expkey key; |
102 | struct svc_expkey *ek; | ||
109 | 103 | ||
110 | if (mesg[mlen-1] != '\n') | 104 | if (mesg[mlen-1] != '\n') |
111 | return -EINVAL; | 105 | return -EINVAL; |
@@ -150,40 +144,38 @@ static int expkey_parse(struct cache_detail *cd, char *mesg, int mlen) | |||
150 | key.ek_fsidtype = fsidtype; | 144 | key.ek_fsidtype = fsidtype; |
151 | memcpy(key.ek_fsid, buf, len); | 145 | memcpy(key.ek_fsid, buf, len); |
152 | 146 | ||
147 | ek = svc_expkey_lookup(&key); | ||
148 | err = -ENOMEM; | ||
149 | if (!ek) | ||
150 | goto out; | ||
151 | |||
153 | /* now we want a pathname, or empty meaning NEGATIVE */ | 152 | /* now we want a pathname, or empty meaning NEGATIVE */ |
153 | err = -EINVAL; | ||
154 | if ((len=qword_get(&mesg, buf, PAGE_SIZE)) < 0) | 154 | if ((len=qword_get(&mesg, buf, PAGE_SIZE)) < 0) |
155 | goto out; | 155 | goto out; |
156 | dprintk("Path seems to be <%s>\n", buf); | 156 | dprintk("Path seems to be <%s>\n", buf); |
157 | err = 0; | 157 | err = 0; |
158 | if (len == 0) { | 158 | if (len == 0) { |
159 | struct svc_expkey *ek; | ||
160 | set_bit(CACHE_NEGATIVE, &key.h.flags); | 159 | set_bit(CACHE_NEGATIVE, &key.h.flags); |
161 | ek = svc_expkey_lookup(&key, 1); | 160 | ek = svc_expkey_update(&key, ek); |
162 | if (ek) | 161 | if (ek) |
163 | expkey_put(&ek->h, &svc_expkey_cache); | 162 | cache_put(&ek->h, &svc_expkey_cache); |
163 | else err = -ENOMEM; | ||
164 | } else { | 164 | } else { |
165 | struct nameidata nd; | 165 | struct nameidata nd; |
166 | struct svc_expkey *ek; | ||
167 | struct svc_export *exp; | ||
168 | err = path_lookup(buf, 0, &nd); | 166 | err = path_lookup(buf, 0, &nd); |
169 | if (err) | 167 | if (err) |
170 | goto out; | 168 | goto out; |
171 | 169 | ||
172 | dprintk("Found the path %s\n", buf); | 170 | dprintk("Found the path %s\n", buf); |
173 | exp = exp_get_by_name(dom, nd.mnt, nd.dentry, NULL); | 171 | key.ek_mnt = nd.mnt; |
174 | 172 | key.ek_dentry = nd.dentry; | |
175 | err = -ENOENT; | ||
176 | if (!exp) | ||
177 | goto out_nd; | ||
178 | key.ek_export = exp; | ||
179 | dprintk("And found export\n"); | ||
180 | 173 | ||
181 | ek = svc_expkey_lookup(&key, 1); | 174 | ek = svc_expkey_update(&key, ek); |
182 | if (ek) | 175 | if (ek) |
183 | expkey_put(&ek->h, &svc_expkey_cache); | 176 | cache_put(&ek->h, &svc_expkey_cache); |
184 | exp_put(exp); | 177 | else |
185 | err = 0; | 178 | err = -ENOMEM; |
186 | out_nd: | ||
187 | path_release(&nd); | 179 | path_release(&nd); |
188 | } | 180 | } |
189 | cache_flush(); | 181 | cache_flush(); |
@@ -214,35 +206,31 @@ static int expkey_show(struct seq_file *m, | |||
214 | if (test_bit(CACHE_VALID, &h->flags) && | 206 | if (test_bit(CACHE_VALID, &h->flags) && |
215 | !test_bit(CACHE_NEGATIVE, &h->flags)) { | 207 | !test_bit(CACHE_NEGATIVE, &h->flags)) { |
216 | seq_printf(m, " "); | 208 | seq_printf(m, " "); |
217 | seq_path(m, ek->ek_export->ex_mnt, ek->ek_export->ex_dentry, "\\ \t\n"); | 209 | seq_path(m, ek->ek_mnt, ek->ek_dentry, "\\ \t\n"); |
218 | } | 210 | } |
219 | seq_printf(m, "\n"); | 211 | seq_printf(m, "\n"); |
220 | return 0; | 212 | return 0; |
221 | } | 213 | } |
222 | |||
223 | struct cache_detail svc_expkey_cache = { | ||
224 | .owner = THIS_MODULE, | ||
225 | .hash_size = EXPKEY_HASHMAX, | ||
226 | .hash_table = expkey_table, | ||
227 | .name = "nfsd.fh", | ||
228 | .cache_put = expkey_put, | ||
229 | .cache_request = expkey_request, | ||
230 | .cache_parse = expkey_parse, | ||
231 | .cache_show = expkey_show, | ||
232 | }; | ||
233 | 214 | ||
234 | static inline int svc_expkey_match (struct svc_expkey *a, struct svc_expkey *b) | 215 | static inline int expkey_match (struct cache_head *a, struct cache_head *b) |
235 | { | 216 | { |
236 | if (a->ek_fsidtype != b->ek_fsidtype || | 217 | struct svc_expkey *orig = container_of(a, struct svc_expkey, h); |
237 | a->ek_client != b->ek_client || | 218 | struct svc_expkey *new = container_of(b, struct svc_expkey, h); |
238 | memcmp(a->ek_fsid, b->ek_fsid, key_len(a->ek_fsidtype)) != 0) | 219 | |
220 | if (orig->ek_fsidtype != new->ek_fsidtype || | ||
221 | orig->ek_client != new->ek_client || | ||
222 | memcmp(orig->ek_fsid, new->ek_fsid, key_len(orig->ek_fsidtype)) != 0) | ||
239 | return 0; | 223 | return 0; |
240 | return 1; | 224 | return 1; |
241 | } | 225 | } |
242 | 226 | ||
243 | static inline void svc_expkey_init(struct svc_expkey *new, struct svc_expkey *item) | 227 | static inline void expkey_init(struct cache_head *cnew, |
228 | struct cache_head *citem) | ||
244 | { | 229 | { |
245 | cache_get(&item->ek_client->h); | 230 | struct svc_expkey *new = container_of(cnew, struct svc_expkey, h); |
231 | struct svc_expkey *item = container_of(citem, struct svc_expkey, h); | ||
232 | |||
233 | kref_get(&item->ek_client->ref); | ||
246 | new->ek_client = item->ek_client; | 234 | new->ek_client = item->ek_client; |
247 | new->ek_fsidtype = item->ek_fsidtype; | 235 | new->ek_fsidtype = item->ek_fsidtype; |
248 | new->ek_fsid[0] = item->ek_fsid[0]; | 236 | new->ek_fsid[0] = item->ek_fsid[0]; |
@@ -250,39 +238,94 @@ static inline void svc_expkey_init(struct svc_expkey *new, struct svc_expkey *it | |||
250 | new->ek_fsid[2] = item->ek_fsid[2]; | 238 | new->ek_fsid[2] = item->ek_fsid[2]; |
251 | } | 239 | } |
252 | 240 | ||
253 | static inline void svc_expkey_update(struct svc_expkey *new, struct svc_expkey *item) | 241 | static inline void expkey_update(struct cache_head *cnew, |
242 | struct cache_head *citem) | ||
243 | { | ||
244 | struct svc_expkey *new = container_of(cnew, struct svc_expkey, h); | ||
245 | struct svc_expkey *item = container_of(citem, struct svc_expkey, h); | ||
246 | |||
247 | new->ek_mnt = mntget(item->ek_mnt); | ||
248 | new->ek_dentry = dget(item->ek_dentry); | ||
249 | } | ||
250 | |||
251 | static struct cache_head *expkey_alloc(void) | ||
254 | { | 252 | { |
255 | cache_get(&item->ek_export->h); | 253 | struct svc_expkey *i = kmalloc(sizeof(*i), GFP_KERNEL); |
256 | new->ek_export = item->ek_export; | 254 | if (i) |
255 | return &i->h; | ||
256 | else | ||
257 | return NULL; | ||
257 | } | 258 | } |
258 | 259 | ||
259 | static DefineSimpleCacheLookup(svc_expkey,0) /* no inplace updates */ | 260 | static struct cache_detail svc_expkey_cache = { |
261 | .owner = THIS_MODULE, | ||
262 | .hash_size = EXPKEY_HASHMAX, | ||
263 | .hash_table = expkey_table, | ||
264 | .name = "nfsd.fh", | ||
265 | .cache_put = expkey_put, | ||
266 | .cache_request = expkey_request, | ||
267 | .cache_parse = expkey_parse, | ||
268 | .cache_show = expkey_show, | ||
269 | .match = expkey_match, | ||
270 | .init = expkey_init, | ||
271 | .update = expkey_update, | ||
272 | .alloc = expkey_alloc, | ||
273 | }; | ||
260 | 274 | ||
261 | #define EXPORT_HASHBITS 8 | 275 | static struct svc_expkey * |
262 | #define EXPORT_HASHMAX (1<< EXPORT_HASHBITS) | 276 | svc_expkey_lookup(struct svc_expkey *item) |
263 | #define EXPORT_HASHMASK (EXPORT_HASHMAX -1) | 277 | { |
278 | struct cache_head *ch; | ||
279 | int hash = item->ek_fsidtype; | ||
280 | char * cp = (char*)item->ek_fsid; | ||
281 | int len = key_len(item->ek_fsidtype); | ||
264 | 282 | ||
265 | static struct cache_head *export_table[EXPORT_HASHMAX]; | 283 | hash ^= hash_mem(cp, len, EXPKEY_HASHBITS); |
284 | hash ^= hash_ptr(item->ek_client, EXPKEY_HASHBITS); | ||
285 | hash &= EXPKEY_HASHMASK; | ||
266 | 286 | ||
267 | static inline int svc_export_hash(struct svc_export *item) | 287 | ch = sunrpc_cache_lookup(&svc_expkey_cache, &item->h, |
288 | hash); | ||
289 | if (ch) | ||
290 | return container_of(ch, struct svc_expkey, h); | ||
291 | else | ||
292 | return NULL; | ||
293 | } | ||
294 | |||
295 | static struct svc_expkey * | ||
296 | svc_expkey_update(struct svc_expkey *new, struct svc_expkey *old) | ||
268 | { | 297 | { |
269 | int rv; | 298 | struct cache_head *ch; |
299 | int hash = new->ek_fsidtype; | ||
300 | char * cp = (char*)new->ek_fsid; | ||
301 | int len = key_len(new->ek_fsidtype); | ||
270 | 302 | ||
271 | rv = hash_ptr(item->ex_client, EXPORT_HASHBITS); | 303 | hash ^= hash_mem(cp, len, EXPKEY_HASHBITS); |
272 | rv ^= hash_ptr(item->ex_dentry, EXPORT_HASHBITS); | 304 | hash ^= hash_ptr(new->ek_client, EXPKEY_HASHBITS); |
273 | rv ^= hash_ptr(item->ex_mnt, EXPORT_HASHBITS); | 305 | hash &= EXPKEY_HASHMASK; |
274 | return rv; | 306 | |
307 | ch = sunrpc_cache_update(&svc_expkey_cache, &new->h, | ||
308 | &old->h, hash); | ||
309 | if (ch) | ||
310 | return container_of(ch, struct svc_expkey, h); | ||
311 | else | ||
312 | return NULL; | ||
275 | } | 313 | } |
276 | 314 | ||
277 | void svc_export_put(struct cache_head *item, struct cache_detail *cd) | 315 | |
316 | #define EXPORT_HASHBITS 8 | ||
317 | #define EXPORT_HASHMAX (1<< EXPORT_HASHBITS) | ||
318 | #define EXPORT_HASHMASK (EXPORT_HASHMAX -1) | ||
319 | |||
320 | static struct cache_head *export_table[EXPORT_HASHMAX]; | ||
321 | |||
322 | static void svc_export_put(struct kref *ref) | ||
278 | { | 323 | { |
279 | if (cache_put(item, cd)) { | 324 | struct svc_export *exp = container_of(ref, struct svc_export, h.ref); |
280 | struct svc_export *exp = container_of(item, struct svc_export, h); | 325 | dput(exp->ex_dentry); |
281 | dput(exp->ex_dentry); | 326 | mntput(exp->ex_mnt); |
282 | mntput(exp->ex_mnt); | 327 | auth_domain_put(exp->ex_client); |
283 | auth_domain_put(exp->ex_client); | 328 | kfree(exp); |
284 | kfree(exp); | ||
285 | } | ||
286 | } | 329 | } |
287 | 330 | ||
288 | static void svc_export_request(struct cache_detail *cd, | 331 | static void svc_export_request(struct cache_detail *cd, |
@@ -304,7 +347,9 @@ static void svc_export_request(struct cache_detail *cd, | |||
304 | (*bpp)[-1] = '\n'; | 347 | (*bpp)[-1] = '\n'; |
305 | } | 348 | } |
306 | 349 | ||
307 | static struct svc_export *svc_export_lookup(struct svc_export *, int); | 350 | static struct svc_export *svc_export_update(struct svc_export *new, |
351 | struct svc_export *old); | ||
352 | static struct svc_export *svc_export_lookup(struct svc_export *); | ||
308 | 353 | ||
309 | static int check_export(struct inode *inode, int flags) | 354 | static int check_export(struct inode *inode, int flags) |
310 | { | 355 | { |
@@ -417,11 +462,16 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen) | |||
417 | if (err) goto out; | 462 | if (err) goto out; |
418 | } | 463 | } |
419 | 464 | ||
420 | expp = svc_export_lookup(&exp, 1); | 465 | expp = svc_export_lookup(&exp); |
421 | if (expp) | 466 | if (expp) |
422 | exp_put(expp); | 467 | expp = svc_export_update(&exp, expp); |
423 | err = 0; | 468 | else |
469 | err = -ENOMEM; | ||
424 | cache_flush(); | 470 | cache_flush(); |
471 | if (expp == NULL) | ||
472 | err = -ENOMEM; | ||
473 | else | ||
474 | exp_put(expp); | ||
425 | out: | 475 | out: |
426 | if (nd.dentry) | 476 | if (nd.dentry) |
427 | path_release(&nd); | 477 | path_release(&nd); |
@@ -455,6 +505,46 @@ static int svc_export_show(struct seq_file *m, | |||
455 | seq_puts(m, ")\n"); | 505 | seq_puts(m, ")\n"); |
456 | return 0; | 506 | return 0; |
457 | } | 507 | } |
508 | static int svc_export_match(struct cache_head *a, struct cache_head *b) | ||
509 | { | ||
510 | struct svc_export *orig = container_of(a, struct svc_export, h); | ||
511 | struct svc_export *new = container_of(b, struct svc_export, h); | ||
512 | return orig->ex_client == new->ex_client && | ||
513 | orig->ex_dentry == new->ex_dentry && | ||
514 | orig->ex_mnt == new->ex_mnt; | ||
515 | } | ||
516 | |||
517 | static void svc_export_init(struct cache_head *cnew, struct cache_head *citem) | ||
518 | { | ||
519 | struct svc_export *new = container_of(cnew, struct svc_export, h); | ||
520 | struct svc_export *item = container_of(citem, struct svc_export, h); | ||
521 | |||
522 | kref_get(&item->ex_client->ref); | ||
523 | new->ex_client = item->ex_client; | ||
524 | new->ex_dentry = dget(item->ex_dentry); | ||
525 | new->ex_mnt = mntget(item->ex_mnt); | ||
526 | } | ||
527 | |||
528 | static void export_update(struct cache_head *cnew, struct cache_head *citem) | ||
529 | { | ||
530 | struct svc_export *new = container_of(cnew, struct svc_export, h); | ||
531 | struct svc_export *item = container_of(citem, struct svc_export, h); | ||
532 | |||
533 | new->ex_flags = item->ex_flags; | ||
534 | new->ex_anon_uid = item->ex_anon_uid; | ||
535 | new->ex_anon_gid = item->ex_anon_gid; | ||
536 | new->ex_fsid = item->ex_fsid; | ||
537 | } | ||
538 | |||
539 | static struct cache_head *svc_export_alloc(void) | ||
540 | { | ||
541 | struct svc_export *i = kmalloc(sizeof(*i), GFP_KERNEL); | ||
542 | if (i) | ||
543 | return &i->h; | ||
544 | else | ||
545 | return NULL; | ||
546 | } | ||
547 | |||
458 | struct cache_detail svc_export_cache = { | 548 | struct cache_detail svc_export_cache = { |
459 | .owner = THIS_MODULE, | 549 | .owner = THIS_MODULE, |
460 | .hash_size = EXPORT_HASHMAX, | 550 | .hash_size = EXPORT_HASHMAX, |
@@ -464,34 +554,49 @@ struct cache_detail svc_export_cache = { | |||
464 | .cache_request = svc_export_request, | 554 | .cache_request = svc_export_request, |
465 | .cache_parse = svc_export_parse, | 555 | .cache_parse = svc_export_parse, |
466 | .cache_show = svc_export_show, | 556 | .cache_show = svc_export_show, |
557 | .match = svc_export_match, | ||
558 | .init = svc_export_init, | ||
559 | .update = export_update, | ||
560 | .alloc = svc_export_alloc, | ||
467 | }; | 561 | }; |
468 | 562 | ||
469 | static inline int svc_export_match(struct svc_export *a, struct svc_export *b) | 563 | static struct svc_export * |
564 | svc_export_lookup(struct svc_export *exp) | ||
470 | { | 565 | { |
471 | return a->ex_client == b->ex_client && | 566 | struct cache_head *ch; |
472 | a->ex_dentry == b->ex_dentry && | 567 | int hash; |
473 | a->ex_mnt == b->ex_mnt; | 568 | hash = hash_ptr(exp->ex_client, EXPORT_HASHBITS); |
474 | } | 569 | hash ^= hash_ptr(exp->ex_dentry, EXPORT_HASHBITS); |
475 | static inline void svc_export_init(struct svc_export *new, struct svc_export *item) | 570 | hash ^= hash_ptr(exp->ex_mnt, EXPORT_HASHBITS); |
476 | { | 571 | |
477 | cache_get(&item->ex_client->h); | 572 | ch = sunrpc_cache_lookup(&svc_export_cache, &exp->h, |
478 | new->ex_client = item->ex_client; | 573 | hash); |
479 | new->ex_dentry = dget(item->ex_dentry); | 574 | if (ch) |
480 | new->ex_mnt = mntget(item->ex_mnt); | 575 | return container_of(ch, struct svc_export, h); |
576 | else | ||
577 | return NULL; | ||
481 | } | 578 | } |
482 | 579 | ||
483 | static inline void svc_export_update(struct svc_export *new, struct svc_export *item) | 580 | static struct svc_export * |
581 | svc_export_update(struct svc_export *new, struct svc_export *old) | ||
484 | { | 582 | { |
485 | new->ex_flags = item->ex_flags; | 583 | struct cache_head *ch; |
486 | new->ex_anon_uid = item->ex_anon_uid; | 584 | int hash; |
487 | new->ex_anon_gid = item->ex_anon_gid; | 585 | hash = hash_ptr(old->ex_client, EXPORT_HASHBITS); |
488 | new->ex_fsid = item->ex_fsid; | 586 | hash ^= hash_ptr(old->ex_dentry, EXPORT_HASHBITS); |
587 | hash ^= hash_ptr(old->ex_mnt, EXPORT_HASHBITS); | ||
588 | |||
589 | ch = sunrpc_cache_update(&svc_export_cache, &new->h, | ||
590 | &old->h, | ||
591 | hash); | ||
592 | if (ch) | ||
593 | return container_of(ch, struct svc_export, h); | ||
594 | else | ||
595 | return NULL; | ||
489 | } | 596 | } |
490 | 597 | ||
491 | static DefineSimpleCacheLookup(svc_export,1) /* allow inplace updates */ | ||
492 | 598 | ||
493 | 599 | static struct svc_expkey * | |
494 | struct svc_expkey * | ||
495 | exp_find_key(svc_client *clp, int fsid_type, u32 *fsidv, struct cache_req *reqp) | 600 | exp_find_key(svc_client *clp, int fsid_type, u32 *fsidv, struct cache_req *reqp) |
496 | { | 601 | { |
497 | struct svc_expkey key, *ek; | 602 | struct svc_expkey key, *ek; |
@@ -504,7 +609,7 @@ exp_find_key(svc_client *clp, int fsid_type, u32 *fsidv, struct cache_req *reqp) | |||
504 | key.ek_fsidtype = fsid_type; | 609 | key.ek_fsidtype = fsid_type; |
505 | memcpy(key.ek_fsid, fsidv, key_len(fsid_type)); | 610 | memcpy(key.ek_fsid, fsidv, key_len(fsid_type)); |
506 | 611 | ||
507 | ek = svc_expkey_lookup(&key, 0); | 612 | ek = svc_expkey_lookup(&key); |
508 | if (ek != NULL) | 613 | if (ek != NULL) |
509 | if ((err = cache_check(&svc_expkey_cache, &ek->h, reqp))) | 614 | if ((err = cache_check(&svc_expkey_cache, &ek->h, reqp))) |
510 | ek = ERR_PTR(err); | 615 | ek = ERR_PTR(err); |
@@ -519,13 +624,16 @@ static int exp_set_key(svc_client *clp, int fsid_type, u32 *fsidv, | |||
519 | key.ek_client = clp; | 624 | key.ek_client = clp; |
520 | key.ek_fsidtype = fsid_type; | 625 | key.ek_fsidtype = fsid_type; |
521 | memcpy(key.ek_fsid, fsidv, key_len(fsid_type)); | 626 | memcpy(key.ek_fsid, fsidv, key_len(fsid_type)); |
522 | key.ek_export = exp; | 627 | key.ek_mnt = exp->ex_mnt; |
628 | key.ek_dentry = exp->ex_dentry; | ||
523 | key.h.expiry_time = NEVER; | 629 | key.h.expiry_time = NEVER; |
524 | key.h.flags = 0; | 630 | key.h.flags = 0; |
525 | 631 | ||
526 | ek = svc_expkey_lookup(&key, 1); | 632 | ek = svc_expkey_lookup(&key); |
633 | if (ek) | ||
634 | ek = svc_expkey_update(&key,ek); | ||
527 | if (ek) { | 635 | if (ek) { |
528 | expkey_put(&ek->h, &svc_expkey_cache); | 636 | cache_put(&ek->h, &svc_expkey_cache); |
529 | return 0; | 637 | return 0; |
530 | } | 638 | } |
531 | return -ENOMEM; | 639 | return -ENOMEM; |
@@ -573,7 +681,7 @@ exp_get_by_name(svc_client *clp, struct vfsmount *mnt, struct dentry *dentry, | |||
573 | key.ex_mnt = mnt; | 681 | key.ex_mnt = mnt; |
574 | key.ex_dentry = dentry; | 682 | key.ex_dentry = dentry; |
575 | 683 | ||
576 | exp = svc_export_lookup(&key, 0); | 684 | exp = svc_export_lookup(&key); |
577 | if (exp != NULL) | 685 | if (exp != NULL) |
578 | switch (cache_check(&svc_export_cache, &exp->h, reqp)) { | 686 | switch (cache_check(&svc_export_cache, &exp->h, reqp)) { |
579 | case 0: break; | 687 | case 0: break; |
@@ -654,7 +762,7 @@ static void exp_fsid_unhash(struct svc_export *exp) | |||
654 | ek = exp_get_fsid_key(exp->ex_client, exp->ex_fsid); | 762 | ek = exp_get_fsid_key(exp->ex_client, exp->ex_fsid); |
655 | if (ek && !IS_ERR(ek)) { | 763 | if (ek && !IS_ERR(ek)) { |
656 | ek->h.expiry_time = get_seconds()-1; | 764 | ek->h.expiry_time = get_seconds()-1; |
657 | expkey_put(&ek->h, &svc_expkey_cache); | 765 | cache_put(&ek->h, &svc_expkey_cache); |
658 | } | 766 | } |
659 | svc_expkey_cache.nextcheck = get_seconds(); | 767 | svc_expkey_cache.nextcheck = get_seconds(); |
660 | } | 768 | } |
@@ -692,7 +800,7 @@ static void exp_unhash(struct svc_export *exp) | |||
692 | ek = exp_get_key(exp->ex_client, inode->i_sb->s_dev, inode->i_ino); | 800 | ek = exp_get_key(exp->ex_client, inode->i_sb->s_dev, inode->i_ino); |
693 | if (ek && !IS_ERR(ek)) { | 801 | if (ek && !IS_ERR(ek)) { |
694 | ek->h.expiry_time = get_seconds()-1; | 802 | ek->h.expiry_time = get_seconds()-1; |
695 | expkey_put(&ek->h, &svc_expkey_cache); | 803 | cache_put(&ek->h, &svc_expkey_cache); |
696 | } | 804 | } |
697 | svc_expkey_cache.nextcheck = get_seconds(); | 805 | svc_expkey_cache.nextcheck = get_seconds(); |
698 | } | 806 | } |
@@ -741,8 +849,8 @@ exp_export(struct nfsctl_export *nxp) | |||
741 | if ((nxp->ex_flags & NFSEXP_FSID) && | 849 | if ((nxp->ex_flags & NFSEXP_FSID) && |
742 | (fsid_key = exp_get_fsid_key(clp, nxp->ex_dev)) && | 850 | (fsid_key = exp_get_fsid_key(clp, nxp->ex_dev)) && |
743 | !IS_ERR(fsid_key) && | 851 | !IS_ERR(fsid_key) && |
744 | fsid_key->ek_export && | 852 | fsid_key->ek_mnt && |
745 | fsid_key->ek_export != exp) | 853 | (fsid_key->ek_mnt != nd.mnt || fsid_key->ek_dentry != nd.dentry) ) |
746 | goto finish; | 854 | goto finish; |
747 | 855 | ||
748 | if (exp) { | 856 | if (exp) { |
@@ -775,13 +883,13 @@ exp_export(struct nfsctl_export *nxp) | |||
775 | new.ex_anon_gid = nxp->ex_anon_gid; | 883 | new.ex_anon_gid = nxp->ex_anon_gid; |
776 | new.ex_fsid = nxp->ex_dev; | 884 | new.ex_fsid = nxp->ex_dev; |
777 | 885 | ||
778 | exp = svc_export_lookup(&new, 1); | 886 | exp = svc_export_lookup(&new); |
887 | if (exp) | ||
888 | exp = svc_export_update(&new, exp); | ||
779 | 889 | ||
780 | if (exp == NULL) | 890 | if (!exp) |
781 | goto finish; | 891 | goto finish; |
782 | 892 | ||
783 | err = 0; | ||
784 | |||
785 | if (exp_hash(clp, exp) || | 893 | if (exp_hash(clp, exp) || |
786 | exp_fsid_hash(clp, exp)) { | 894 | exp_fsid_hash(clp, exp)) { |
787 | /* failed to create at least one index */ | 895 | /* failed to create at least one index */ |
@@ -794,7 +902,7 @@ finish: | |||
794 | if (exp) | 902 | if (exp) |
795 | exp_put(exp); | 903 | exp_put(exp); |
796 | if (fsid_key && !IS_ERR(fsid_key)) | 904 | if (fsid_key && !IS_ERR(fsid_key)) |
797 | expkey_put(&fsid_key->h, &svc_expkey_cache); | 905 | cache_put(&fsid_key->h, &svc_expkey_cache); |
798 | if (clp) | 906 | if (clp) |
799 | auth_domain_put(clp); | 907 | auth_domain_put(clp); |
800 | path_release(&nd); | 908 | path_release(&nd); |
@@ -912,6 +1020,24 @@ out: | |||
912 | return err; | 1020 | return err; |
913 | } | 1021 | } |
914 | 1022 | ||
1023 | struct svc_export * | ||
1024 | exp_find(struct auth_domain *clp, int fsid_type, u32 *fsidv, | ||
1025 | struct cache_req *reqp) | ||
1026 | { | ||
1027 | struct svc_export *exp; | ||
1028 | struct svc_expkey *ek = exp_find_key(clp, fsid_type, fsidv, reqp); | ||
1029 | if (!ek || IS_ERR(ek)) | ||
1030 | return ERR_PTR(PTR_ERR(ek)); | ||
1031 | |||
1032 | exp = exp_get_by_name(clp, ek->ek_mnt, ek->ek_dentry, reqp); | ||
1033 | cache_put(&ek->h, &svc_expkey_cache); | ||
1034 | |||
1035 | if (!exp || IS_ERR(exp)) | ||
1036 | return ERR_PTR(PTR_ERR(exp)); | ||
1037 | return exp; | ||
1038 | } | ||
1039 | |||
1040 | |||
915 | /* | 1041 | /* |
916 | * Called when we need the filehandle for the root of the pseudofs, | 1042 | * Called when we need the filehandle for the root of the pseudofs, |
917 | * for a given NFSv4 client. The root is defined to be the | 1043 | * for a given NFSv4 client. The root is defined to be the |
@@ -922,6 +1048,7 @@ exp_pseudoroot(struct auth_domain *clp, struct svc_fh *fhp, | |||
922 | struct cache_req *creq) | 1048 | struct cache_req *creq) |
923 | { | 1049 | { |
924 | struct svc_expkey *fsid_key; | 1050 | struct svc_expkey *fsid_key; |
1051 | struct svc_export *exp; | ||
925 | int rv; | 1052 | int rv; |
926 | u32 fsidv[2]; | 1053 | u32 fsidv[2]; |
927 | 1054 | ||
@@ -933,9 +1060,15 @@ exp_pseudoroot(struct auth_domain *clp, struct svc_fh *fhp, | |||
933 | if (!fsid_key || IS_ERR(fsid_key)) | 1060 | if (!fsid_key || IS_ERR(fsid_key)) |
934 | return nfserr_perm; | 1061 | return nfserr_perm; |
935 | 1062 | ||
936 | rv = fh_compose(fhp, fsid_key->ek_export, | 1063 | exp = exp_get_by_name(clp, fsid_key->ek_mnt, fsid_key->ek_dentry, creq); |
937 | fsid_key->ek_export->ex_dentry, NULL); | 1064 | if (exp == NULL) |
938 | expkey_put(&fsid_key->h, &svc_expkey_cache); | 1065 | rv = nfserr_perm; |
1066 | else if (IS_ERR(exp)) | ||
1067 | rv = nfserrno(PTR_ERR(exp)); | ||
1068 | else | ||
1069 | rv = fh_compose(fhp, exp, | ||
1070 | fsid_key->ek_dentry, NULL); | ||
1071 | cache_put(&fsid_key->h, &svc_expkey_cache); | ||
939 | return rv; | 1072 | return rv; |
940 | } | 1073 | } |
941 | 1074 | ||
@@ -1054,7 +1187,7 @@ static int e_show(struct seq_file *m, void *p) | |||
1054 | cache_get(&exp->h); | 1187 | cache_get(&exp->h); |
1055 | if (cache_check(&svc_export_cache, &exp->h, NULL)) | 1188 | if (cache_check(&svc_export_cache, &exp->h, NULL)) |
1056 | return 0; | 1189 | return 0; |
1057 | if (cache_put(&exp->h, &svc_export_cache)) BUG(); | 1190 | cache_put(&exp->h, &svc_export_cache); |
1058 | return svc_export_show(m, &svc_export_cache, cp); | 1191 | return svc_export_show(m, &svc_export_cache, cp); |
1059 | } | 1192 | } |
1060 | 1193 | ||
@@ -1129,7 +1262,6 @@ exp_delclient(struct nfsctl_client *ncp) | |||
1129 | */ | 1262 | */ |
1130 | if (dom) { | 1263 | if (dom) { |
1131 | err = auth_unix_forget_old(dom); | 1264 | err = auth_unix_forget_old(dom); |
1132 | dom->h.expiry_time = get_seconds(); | ||
1133 | auth_domain_put(dom); | 1265 | auth_domain_put(dom); |
1134 | } | 1266 | } |
1135 | 1267 | ||
diff --git a/fs/nfsd/nfs4idmap.c b/fs/nfsd/nfs4idmap.c index 13369650cdf9..4b6aa60dfceb 100644 --- a/fs/nfsd/nfs4idmap.c +++ b/fs/nfsd/nfs4idmap.c | |||
@@ -76,21 +76,18 @@ struct ent { | |||
76 | char authname[IDMAP_NAMESZ]; | 76 | char authname[IDMAP_NAMESZ]; |
77 | }; | 77 | }; |
78 | 78 | ||
79 | #define DefineSimpleCacheLookupMap(STRUCT, FUNC) \ | ||
80 | DefineCacheLookup(struct STRUCT, h, FUNC##_lookup, \ | ||
81 | (struct STRUCT *item, int set), /*no setup */, \ | ||
82 | & FUNC##_cache, FUNC##_hash(item), FUNC##_match(item, tmp), \ | ||
83 | STRUCT##_init(new, item), STRUCT##_update(tmp, item), 0) | ||
84 | |||
85 | /* Common entry handling */ | 79 | /* Common entry handling */ |
86 | 80 | ||
87 | #define ENT_HASHBITS 8 | 81 | #define ENT_HASHBITS 8 |
88 | #define ENT_HASHMAX (1 << ENT_HASHBITS) | 82 | #define ENT_HASHMAX (1 << ENT_HASHBITS) |
89 | #define ENT_HASHMASK (ENT_HASHMAX - 1) | 83 | #define ENT_HASHMASK (ENT_HASHMAX - 1) |
90 | 84 | ||
91 | static inline void | 85 | static void |
92 | ent_init(struct ent *new, struct ent *itm) | 86 | ent_init(struct cache_head *cnew, struct cache_head *citm) |
93 | { | 87 | { |
88 | struct ent *new = container_of(cnew, struct ent, h); | ||
89 | struct ent *itm = container_of(citm, struct ent, h); | ||
90 | |||
94 | new->id = itm->id; | 91 | new->id = itm->id; |
95 | new->type = itm->type; | 92 | new->type = itm->type; |
96 | 93 | ||
@@ -98,19 +95,21 @@ ent_init(struct ent *new, struct ent *itm) | |||
98 | strlcpy(new->authname, itm->authname, sizeof(new->name)); | 95 | strlcpy(new->authname, itm->authname, sizeof(new->name)); |
99 | } | 96 | } |
100 | 97 | ||
101 | static inline void | 98 | static void |
102 | ent_update(struct ent *new, struct ent *itm) | 99 | ent_put(struct kref *ref) |
103 | { | 100 | { |
104 | ent_init(new, itm); | 101 | struct ent *map = container_of(ref, struct ent, h.ref); |
102 | kfree(map); | ||
105 | } | 103 | } |
106 | 104 | ||
107 | static void | 105 | static struct cache_head * |
108 | ent_put(struct cache_head *ch, struct cache_detail *cd) | 106 | ent_alloc(void) |
109 | { | 107 | { |
110 | if (cache_put(ch, cd)) { | 108 | struct ent *e = kmalloc(sizeof(*e), GFP_KERNEL); |
111 | struct ent *map = container_of(ch, struct ent, h); | 109 | if (e) |
112 | kfree(map); | 110 | return &e->h; |
113 | } | 111 | else |
112 | return NULL; | ||
114 | } | 113 | } |
115 | 114 | ||
116 | /* | 115 | /* |
@@ -149,9 +148,12 @@ idtoname_request(struct cache_detail *cd, struct cache_head *ch, char **bpp, | |||
149 | (*bpp)[-1] = '\n'; | 148 | (*bpp)[-1] = '\n'; |
150 | } | 149 | } |
151 | 150 | ||
152 | static inline int | 151 | static int |
153 | idtoname_match(struct ent *a, struct ent *b) | 152 | idtoname_match(struct cache_head *ca, struct cache_head *cb) |
154 | { | 153 | { |
154 | struct ent *a = container_of(ca, struct ent, h); | ||
155 | struct ent *b = container_of(cb, struct ent, h); | ||
156 | |||
155 | return (a->id == b->id && a->type == b->type && | 157 | return (a->id == b->id && a->type == b->type && |
156 | strcmp(a->authname, b->authname) == 0); | 158 | strcmp(a->authname, b->authname) == 0); |
157 | } | 159 | } |
@@ -184,7 +186,8 @@ warn_no_idmapd(struct cache_detail *detail) | |||
184 | 186 | ||
185 | 187 | ||
186 | static int idtoname_parse(struct cache_detail *, char *, int); | 188 | static int idtoname_parse(struct cache_detail *, char *, int); |
187 | static struct ent *idtoname_lookup(struct ent *, int); | 189 | static struct ent *idtoname_lookup(struct ent *); |
190 | static struct ent *idtoname_update(struct ent *, struct ent *); | ||
188 | 191 | ||
189 | static struct cache_detail idtoname_cache = { | 192 | static struct cache_detail idtoname_cache = { |
190 | .owner = THIS_MODULE, | 193 | .owner = THIS_MODULE, |
@@ -196,6 +199,10 @@ static struct cache_detail idtoname_cache = { | |||
196 | .cache_parse = idtoname_parse, | 199 | .cache_parse = idtoname_parse, |
197 | .cache_show = idtoname_show, | 200 | .cache_show = idtoname_show, |
198 | .warn_no_listener = warn_no_idmapd, | 201 | .warn_no_listener = warn_no_idmapd, |
202 | .match = idtoname_match, | ||
203 | .init = ent_init, | ||
204 | .update = ent_init, | ||
205 | .alloc = ent_alloc, | ||
199 | }; | 206 | }; |
200 | 207 | ||
201 | int | 208 | int |
@@ -238,6 +245,11 @@ idtoname_parse(struct cache_detail *cd, char *buf, int buflen) | |||
238 | if (ent.h.expiry_time == 0) | 245 | if (ent.h.expiry_time == 0) |
239 | goto out; | 246 | goto out; |
240 | 247 | ||
248 | error = -ENOMEM; | ||
249 | res = idtoname_lookup(&ent); | ||
250 | if (!res) | ||
251 | goto out; | ||
252 | |||
241 | /* Name */ | 253 | /* Name */ |
242 | error = qword_get(&buf, buf1, PAGE_SIZE); | 254 | error = qword_get(&buf, buf1, PAGE_SIZE); |
243 | if (error == -EINVAL) | 255 | if (error == -EINVAL) |
@@ -252,10 +264,11 @@ idtoname_parse(struct cache_detail *cd, char *buf, int buflen) | |||
252 | memcpy(ent.name, buf1, sizeof(ent.name)); | 264 | memcpy(ent.name, buf1, sizeof(ent.name)); |
253 | } | 265 | } |
254 | error = -ENOMEM; | 266 | error = -ENOMEM; |
255 | if ((res = idtoname_lookup(&ent, 1)) == NULL) | 267 | res = idtoname_update(&ent, res); |
268 | if (res == NULL) | ||
256 | goto out; | 269 | goto out; |
257 | 270 | ||
258 | ent_put(&res->h, &idtoname_cache); | 271 | cache_put(&res->h, &idtoname_cache); |
259 | 272 | ||
260 | error = 0; | 273 | error = 0; |
261 | out: | 274 | out: |
@@ -264,7 +277,31 @@ out: | |||
264 | return error; | 277 | return error; |
265 | } | 278 | } |
266 | 279 | ||
267 | static DefineSimpleCacheLookupMap(ent, idtoname); | 280 | |
281 | static struct ent * | ||
282 | idtoname_lookup(struct ent *item) | ||
283 | { | ||
284 | struct cache_head *ch = sunrpc_cache_lookup(&idtoname_cache, | ||
285 | &item->h, | ||
286 | idtoname_hash(item)); | ||
287 | if (ch) | ||
288 | return container_of(ch, struct ent, h); | ||
289 | else | ||
290 | return NULL; | ||
291 | } | ||
292 | |||
293 | static struct ent * | ||
294 | idtoname_update(struct ent *new, struct ent *old) | ||
295 | { | ||
296 | struct cache_head *ch = sunrpc_cache_update(&idtoname_cache, | ||
297 | &new->h, &old->h, | ||
298 | idtoname_hash(new)); | ||
299 | if (ch) | ||
300 | return container_of(ch, struct ent, h); | ||
301 | else | ||
302 | return NULL; | ||
303 | } | ||
304 | |||
268 | 305 | ||
269 | /* | 306 | /* |
270 | * Name -> ID cache | 307 | * Name -> ID cache |
@@ -291,9 +328,12 @@ nametoid_request(struct cache_detail *cd, struct cache_head *ch, char **bpp, | |||
291 | (*bpp)[-1] = '\n'; | 328 | (*bpp)[-1] = '\n'; |
292 | } | 329 | } |
293 | 330 | ||
294 | static inline int | 331 | static int |
295 | nametoid_match(struct ent *a, struct ent *b) | 332 | nametoid_match(struct cache_head *ca, struct cache_head *cb) |
296 | { | 333 | { |
334 | struct ent *a = container_of(ca, struct ent, h); | ||
335 | struct ent *b = container_of(cb, struct ent, h); | ||
336 | |||
297 | return (a->type == b->type && strcmp(a->name, b->name) == 0 && | 337 | return (a->type == b->type && strcmp(a->name, b->name) == 0 && |
298 | strcmp(a->authname, b->authname) == 0); | 338 | strcmp(a->authname, b->authname) == 0); |
299 | } | 339 | } |
@@ -317,7 +357,8 @@ nametoid_show(struct seq_file *m, struct cache_detail *cd, struct cache_head *h) | |||
317 | return 0; | 357 | return 0; |
318 | } | 358 | } |
319 | 359 | ||
320 | static struct ent *nametoid_lookup(struct ent *, int); | 360 | static struct ent *nametoid_lookup(struct ent *); |
361 | static struct ent *nametoid_update(struct ent *, struct ent *); | ||
321 | static int nametoid_parse(struct cache_detail *, char *, int); | 362 | static int nametoid_parse(struct cache_detail *, char *, int); |
322 | 363 | ||
323 | static struct cache_detail nametoid_cache = { | 364 | static struct cache_detail nametoid_cache = { |
@@ -330,6 +371,10 @@ static struct cache_detail nametoid_cache = { | |||
330 | .cache_parse = nametoid_parse, | 371 | .cache_parse = nametoid_parse, |
331 | .cache_show = nametoid_show, | 372 | .cache_show = nametoid_show, |
332 | .warn_no_listener = warn_no_idmapd, | 373 | .warn_no_listener = warn_no_idmapd, |
374 | .match = nametoid_match, | ||
375 | .init = ent_init, | ||
376 | .update = ent_init, | ||
377 | .alloc = ent_alloc, | ||
333 | }; | 378 | }; |
334 | 379 | ||
335 | static int | 380 | static int |
@@ -379,10 +424,14 @@ nametoid_parse(struct cache_detail *cd, char *buf, int buflen) | |||
379 | set_bit(CACHE_NEGATIVE, &ent.h.flags); | 424 | set_bit(CACHE_NEGATIVE, &ent.h.flags); |
380 | 425 | ||
381 | error = -ENOMEM; | 426 | error = -ENOMEM; |
382 | if ((res = nametoid_lookup(&ent, 1)) == NULL) | 427 | res = nametoid_lookup(&ent); |
428 | if (res == NULL) | ||
429 | goto out; | ||
430 | res = nametoid_update(&ent, res); | ||
431 | if (res == NULL) | ||
383 | goto out; | 432 | goto out; |
384 | 433 | ||
385 | ent_put(&res->h, &nametoid_cache); | 434 | cache_put(&res->h, &nametoid_cache); |
386 | error = 0; | 435 | error = 0; |
387 | out: | 436 | out: |
388 | kfree(buf1); | 437 | kfree(buf1); |
@@ -390,7 +439,30 @@ out: | |||
390 | return (error); | 439 | return (error); |
391 | } | 440 | } |
392 | 441 | ||
393 | static DefineSimpleCacheLookupMap(ent, nametoid); | 442 | |
443 | static struct ent * | ||
444 | nametoid_lookup(struct ent *item) | ||
445 | { | ||
446 | struct cache_head *ch = sunrpc_cache_lookup(&nametoid_cache, | ||
447 | &item->h, | ||
448 | nametoid_hash(item)); | ||
449 | if (ch) | ||
450 | return container_of(ch, struct ent, h); | ||
451 | else | ||
452 | return NULL; | ||
453 | } | ||
454 | |||
455 | static struct ent * | ||
456 | nametoid_update(struct ent *new, struct ent *old) | ||
457 | { | ||
458 | struct cache_head *ch = sunrpc_cache_update(&nametoid_cache, | ||
459 | &new->h, &old->h, | ||
460 | nametoid_hash(new)); | ||
461 | if (ch) | ||
462 | return container_of(ch, struct ent, h); | ||
463 | else | ||
464 | return NULL; | ||
465 | } | ||
394 | 466 | ||
395 | /* | 467 | /* |
396 | * Exported API | 468 | * Exported API |
@@ -458,24 +530,24 @@ idmap_defer(struct cache_req *req) | |||
458 | } | 530 | } |
459 | 531 | ||
460 | static inline int | 532 | static inline int |
461 | do_idmap_lookup(struct ent *(*lookup_fn)(struct ent *, int), struct ent *key, | 533 | do_idmap_lookup(struct ent *(*lookup_fn)(struct ent *), struct ent *key, |
462 | struct cache_detail *detail, struct ent **item, | 534 | struct cache_detail *detail, struct ent **item, |
463 | struct idmap_defer_req *mdr) | 535 | struct idmap_defer_req *mdr) |
464 | { | 536 | { |
465 | *item = lookup_fn(key, 0); | 537 | *item = lookup_fn(key); |
466 | if (!*item) | 538 | if (!*item) |
467 | return -ENOMEM; | 539 | return -ENOMEM; |
468 | return cache_check(detail, &(*item)->h, &mdr->req); | 540 | return cache_check(detail, &(*item)->h, &mdr->req); |
469 | } | 541 | } |
470 | 542 | ||
471 | static inline int | 543 | static inline int |
472 | do_idmap_lookup_nowait(struct ent *(*lookup_fn)(struct ent *, int), | 544 | do_idmap_lookup_nowait(struct ent *(*lookup_fn)(struct ent *), |
473 | struct ent *key, struct cache_detail *detail, | 545 | struct ent *key, struct cache_detail *detail, |
474 | struct ent **item) | 546 | struct ent **item) |
475 | { | 547 | { |
476 | int ret = -ENOMEM; | 548 | int ret = -ENOMEM; |
477 | 549 | ||
478 | *item = lookup_fn(key, 0); | 550 | *item = lookup_fn(key); |
479 | if (!*item) | 551 | if (!*item) |
480 | goto out_err; | 552 | goto out_err; |
481 | ret = -ETIMEDOUT; | 553 | ret = -ETIMEDOUT; |
@@ -488,7 +560,7 @@ do_idmap_lookup_nowait(struct ent *(*lookup_fn)(struct ent *, int), | |||
488 | goto out_put; | 560 | goto out_put; |
489 | return 0; | 561 | return 0; |
490 | out_put: | 562 | out_put: |
491 | ent_put(&(*item)->h, detail); | 563 | cache_put(&(*item)->h, detail); |
492 | out_err: | 564 | out_err: |
493 | *item = NULL; | 565 | *item = NULL; |
494 | return ret; | 566 | return ret; |
@@ -496,7 +568,7 @@ out_err: | |||
496 | 568 | ||
497 | static int | 569 | static int |
498 | idmap_lookup(struct svc_rqst *rqstp, | 570 | idmap_lookup(struct svc_rqst *rqstp, |
499 | struct ent *(*lookup_fn)(struct ent *, int), struct ent *key, | 571 | struct ent *(*lookup_fn)(struct ent *), struct ent *key, |
500 | struct cache_detail *detail, struct ent **item) | 572 | struct cache_detail *detail, struct ent **item) |
501 | { | 573 | { |
502 | struct idmap_defer_req *mdr; | 574 | struct idmap_defer_req *mdr; |
@@ -539,7 +611,7 @@ idmap_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen | |||
539 | if (ret) | 611 | if (ret) |
540 | return ret; | 612 | return ret; |
541 | *id = item->id; | 613 | *id = item->id; |
542 | ent_put(&item->h, &nametoid_cache); | 614 | cache_put(&item->h, &nametoid_cache); |
543 | return 0; | 615 | return 0; |
544 | } | 616 | } |
545 | 617 | ||
@@ -561,7 +633,7 @@ idmap_id_to_name(struct svc_rqst *rqstp, int type, uid_t id, char *name) | |||
561 | ret = strlen(item->name); | 633 | ret = strlen(item->name); |
562 | BUG_ON(ret > IDMAP_NAMESZ); | 634 | BUG_ON(ret > IDMAP_NAMESZ); |
563 | memcpy(name, item->name, ret); | 635 | memcpy(name, item->name, ret); |
564 | ent_put(&item->h, &idtoname_cache); | 636 | cache_put(&item->h, &idtoname_cache); |
565 | return ret; | 637 | return ret; |
566 | } | 638 | } |
567 | 639 | ||
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index c8960aff0968..3ef017b3b5bd 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c | |||
@@ -134,7 +134,7 @@ static ssize_t nfsctl_transaction_read(struct file *file, char __user *buf, size | |||
134 | return simple_transaction_read(file, buf, size, pos); | 134 | return simple_transaction_read(file, buf, size, pos); |
135 | } | 135 | } |
136 | 136 | ||
137 | static struct file_operations transaction_ops = { | 137 | static const struct file_operations transaction_ops = { |
138 | .write = nfsctl_transaction_write, | 138 | .write = nfsctl_transaction_write, |
139 | .read = nfsctl_transaction_read, | 139 | .read = nfsctl_transaction_read, |
140 | .release = simple_transaction_release, | 140 | .release = simple_transaction_release, |
@@ -146,7 +146,7 @@ static int exports_open(struct inode *inode, struct file *file) | |||
146 | return seq_open(file, &nfs_exports_op); | 146 | return seq_open(file, &nfs_exports_op); |
147 | } | 147 | } |
148 | 148 | ||
149 | static struct file_operations exports_operations = { | 149 | static const struct file_operations exports_operations = { |
150 | .open = exports_open, | 150 | .open = exports_open, |
151 | .read = seq_read, | 151 | .read = seq_read, |
152 | .llseek = seq_lseek, | 152 | .llseek = seq_lseek, |
diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c index 7a3e397b4ed3..3f2ec2e6d06c 100644 --- a/fs/nfsd/nfsfh.c +++ b/fs/nfsd/nfsfh.c | |||
@@ -506,7 +506,7 @@ fh_put(struct svc_fh *fhp) | |||
506 | nfsd_nr_put++; | 506 | nfsd_nr_put++; |
507 | } | 507 | } |
508 | if (exp) { | 508 | if (exp) { |
509 | svc_export_put(&exp->h, &svc_export_cache); | 509 | cache_put(&exp->h, &svc_export_cache); |
510 | fhp->fh_export = NULL; | 510 | fhp->fh_export = NULL; |
511 | } | 511 | } |
512 | return; | 512 | return; |
diff --git a/fs/nfsd/stats.c b/fs/nfsd/stats.c index 1cf955bcc526..57265d563804 100644 --- a/fs/nfsd/stats.c +++ b/fs/nfsd/stats.c | |||
@@ -80,7 +80,7 @@ static int nfsd_proc_open(struct inode *inode, struct file *file) | |||
80 | return single_open(file, nfsd_proc_show, NULL); | 80 | return single_open(file, nfsd_proc_show, NULL); |
81 | } | 81 | } |
82 | 82 | ||
83 | static struct file_operations nfsd_proc_fops = { | 83 | static const struct file_operations nfsd_proc_fops = { |
84 | .owner = THIS_MODULE, | 84 | .owner = THIS_MODULE, |
85 | .open = nfsd_proc_open, | 85 | .open = nfsd_proc_open, |
86 | .read = seq_read, | 86 | .read = seq_read, |
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 5320e5afaddb..31018333dc38 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c | |||
@@ -706,7 +706,7 @@ nfsd_close(struct file *filp) | |||
706 | * after it. | 706 | * after it. |
707 | */ | 707 | */ |
708 | static inline int nfsd_dosync(struct file *filp, struct dentry *dp, | 708 | static inline int nfsd_dosync(struct file *filp, struct dentry *dp, |
709 | struct file_operations *fop) | 709 | const struct file_operations *fop) |
710 | { | 710 | { |
711 | struct inode *inode = dp->d_inode; | 711 | struct inode *inode = dp->d_inode; |
712 | int (*fsync) (struct file *, struct dentry *, int); | 712 | int (*fsync) (struct file *, struct dentry *, int); |