aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/nfs4idmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfsd/nfs4idmap.c')
-rw-r--r--fs/nfsd/nfs4idmap.c146
1 files changed, 109 insertions, 37 deletions
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
91static inline void 85static void
92ent_init(struct ent *new, struct ent *itm) 86ent_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
101static inline void 98static void
102ent_update(struct ent *new, struct ent *itm) 99ent_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
107static void 105static struct cache_head *
108ent_put(struct cache_head *ch, struct cache_detail *cd) 106ent_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
152static inline int 151static int
153idtoname_match(struct ent *a, struct ent *b) 152idtoname_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
186static int idtoname_parse(struct cache_detail *, char *, int); 188static int idtoname_parse(struct cache_detail *, char *, int);
187static struct ent *idtoname_lookup(struct ent *, int); 189static struct ent *idtoname_lookup(struct ent *);
190static struct ent *idtoname_update(struct ent *, struct ent *);
188 191
189static struct cache_detail idtoname_cache = { 192static 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
201int 208int
@@ -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;
261out: 274out:
@@ -264,7 +277,31 @@ out:
264 return error; 277 return error;
265} 278}
266 279
267static DefineSimpleCacheLookupMap(ent, idtoname); 280
281static struct ent *
282idtoname_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
293static struct ent *
294idtoname_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
294static inline int 331static int
295nametoid_match(struct ent *a, struct ent *b) 332nametoid_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
320static struct ent *nametoid_lookup(struct ent *, int); 360static struct ent *nametoid_lookup(struct ent *);
361static struct ent *nametoid_update(struct ent *, struct ent *);
321static int nametoid_parse(struct cache_detail *, char *, int); 362static int nametoid_parse(struct cache_detail *, char *, int);
322 363
323static struct cache_detail nametoid_cache = { 364static 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
335static int 380static 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;
387out: 436out:
388 kfree(buf1); 437 kfree(buf1);
@@ -390,7 +439,30 @@ out:
390 return (error); 439 return (error);
391} 440}
392 441
393static DefineSimpleCacheLookupMap(ent, nametoid); 442
443static struct ent *
444nametoid_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
455static struct ent *
456nametoid_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
460static inline int 532static inline int
461do_idmap_lookup(struct ent *(*lookup_fn)(struct ent *, int), struct ent *key, 533do_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
471static inline int 543static inline int
472do_idmap_lookup_nowait(struct ent *(*lookup_fn)(struct ent *, int), 544do_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;
490out_put: 562out_put:
491 ent_put(&(*item)->h, detail); 563 cache_put(&(*item)->h, detail);
492out_err: 564out_err:
493 *item = NULL; 565 *item = NULL;
494 return ret; 566 return ret;
@@ -496,7 +568,7 @@ out_err:
496 568
497static int 569static int
498idmap_lookup(struct svc_rqst *rqstp, 570idmap_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