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.c126
1 files changed, 103 insertions, 23 deletions
diff --git a/fs/nfsd/nfs4idmap.c b/fs/nfsd/nfs4idmap.c
index dea690aa8bb5..75cfbb68b205 100644
--- a/fs/nfsd/nfs4idmap.c
+++ b/fs/nfsd/nfs4idmap.c
@@ -82,9 +82,12 @@ struct ent {
82#define ENT_HASHMAX (1 << ENT_HASHBITS) 82#define ENT_HASHMAX (1 << ENT_HASHBITS)
83#define ENT_HASHMASK (ENT_HASHMAX - 1) 83#define ENT_HASHMASK (ENT_HASHMAX - 1)
84 84
85static inline void 85static void
86ent_init(struct ent *new, struct ent *itm) 86ent_init(struct cache_head *cnew, struct cache_head *citm)
87{ 87{
88 struct ent *new = container_of(cnew, struct ent, h);
89 struct ent *itm = container_of(citm, struct ent, h);
90
88 new->id = itm->id; 91 new->id = itm->id;
89 new->type = itm->type; 92 new->type = itm->type;
90 93
@@ -92,12 +95,6 @@ ent_init(struct ent *new, struct ent *itm)
92 strlcpy(new->authname, itm->authname, sizeof(new->name)); 95 strlcpy(new->authname, itm->authname, sizeof(new->name));
93} 96}
94 97
95static inline void
96ent_update(struct ent *new, struct ent *itm)
97{
98 ent_init(new, itm);
99}
100
101static void 98static void
102ent_put(struct cache_head *ch, struct cache_detail *cd) 99ent_put(struct cache_head *ch, struct cache_detail *cd)
103{ 100{
@@ -107,6 +104,16 @@ ent_put(struct cache_head *ch, struct cache_detail *cd)
107 } 104 }
108} 105}
109 106
107static struct cache_head *
108ent_alloc(void)
109{
110 struct ent *e = kmalloc(sizeof(*e), GFP_KERNEL);
111 if (e)
112 return &e->h;
113 else
114 return NULL;
115}
116
110/* 117/*
111 * ID -> Name cache 118 * ID -> Name cache
112 */ 119 */
@@ -143,9 +150,12 @@ idtoname_request(struct cache_detail *cd, struct cache_head *ch, char **bpp,
143 (*bpp)[-1] = '\n'; 150 (*bpp)[-1] = '\n';
144} 151}
145 152
146static inline int 153static int
147idtoname_match(struct ent *a, struct ent *b) 154idtoname_match(struct cache_head *ca, struct cache_head *cb)
148{ 155{
156 struct ent *a = container_of(ca, struct ent, h);
157 struct ent *b = container_of(cb, struct ent, h);
158
149 return (a->id == b->id && a->type == b->type && 159 return (a->id == b->id && a->type == b->type &&
150 strcmp(a->authname, b->authname) == 0); 160 strcmp(a->authname, b->authname) == 0);
151} 161}
@@ -178,7 +188,8 @@ warn_no_idmapd(struct cache_detail *detail)
178 188
179 189
180static int idtoname_parse(struct cache_detail *, char *, int); 190static int idtoname_parse(struct cache_detail *, char *, int);
181static struct ent *idtoname_lookup(struct ent *, int); 191static struct ent *idtoname_lookup(struct ent *);
192static struct ent *idtoname_update(struct ent *, struct ent *);
182 193
183static struct cache_detail idtoname_cache = { 194static struct cache_detail idtoname_cache = {
184 .owner = THIS_MODULE, 195 .owner = THIS_MODULE,
@@ -190,6 +201,10 @@ static struct cache_detail idtoname_cache = {
190 .cache_parse = idtoname_parse, 201 .cache_parse = idtoname_parse,
191 .cache_show = idtoname_show, 202 .cache_show = idtoname_show,
192 .warn_no_listener = warn_no_idmapd, 203 .warn_no_listener = warn_no_idmapd,
204 .match = idtoname_match,
205 .init = ent_init,
206 .update = ent_init,
207 .alloc = ent_alloc,
193}; 208};
194 209
195int 210int
@@ -232,6 +247,11 @@ idtoname_parse(struct cache_detail *cd, char *buf, int buflen)
232 if (ent.h.expiry_time == 0) 247 if (ent.h.expiry_time == 0)
233 goto out; 248 goto out;
234 249
250 error = -ENOMEM;
251 res = idtoname_lookup(&ent);
252 if (!res)
253 goto out;
254
235 /* Name */ 255 /* Name */
236 error = qword_get(&buf, buf1, PAGE_SIZE); 256 error = qword_get(&buf, buf1, PAGE_SIZE);
237 if (error == -EINVAL) 257 if (error == -EINVAL)
@@ -246,7 +266,8 @@ idtoname_parse(struct cache_detail *cd, char *buf, int buflen)
246 memcpy(ent.name, buf1, sizeof(ent.name)); 266 memcpy(ent.name, buf1, sizeof(ent.name));
247 } 267 }
248 error = -ENOMEM; 268 error = -ENOMEM;
249 if ((res = idtoname_lookup(&ent, 1)) == NULL) 269 res = idtoname_update(&ent, res);
270 if (res == NULL)
250 goto out; 271 goto out;
251 272
252 ent_put(&res->h, &idtoname_cache); 273 ent_put(&res->h, &idtoname_cache);
@@ -258,7 +279,31 @@ out:
258 return error; 279 return error;
259} 280}
260 281
261static DefineSimpleCacheLookup(ent, idtoname); 282
283static struct ent *
284idtoname_lookup(struct ent *item)
285{
286 struct cache_head *ch = sunrpc_cache_lookup(&idtoname_cache,
287 &item->h,
288 idtoname_hash(item));
289 if (ch)
290 return container_of(ch, struct ent, h);
291 else
292 return NULL;
293}
294
295static struct ent *
296idtoname_update(struct ent *new, struct ent *old)
297{
298 struct cache_head *ch = sunrpc_cache_update(&idtoname_cache,
299 &new->h, &old->h,
300 idtoname_hash(new));
301 if (ch)
302 return container_of(ch, struct ent, h);
303 else
304 return NULL;
305}
306
262 307
263/* 308/*
264 * Name -> ID cache 309 * Name -> ID cache
@@ -285,9 +330,12 @@ nametoid_request(struct cache_detail *cd, struct cache_head *ch, char **bpp,
285 (*bpp)[-1] = '\n'; 330 (*bpp)[-1] = '\n';
286} 331}
287 332
288static inline int 333static int
289nametoid_match(struct ent *a, struct ent *b) 334nametoid_match(struct cache_head *ca, struct cache_head *cb)
290{ 335{
336 struct ent *a = container_of(ca, struct ent, h);
337 struct ent *b = container_of(cb, struct ent, h);
338
291 return (a->type == b->type && strcmp(a->name, b->name) == 0 && 339 return (a->type == b->type && strcmp(a->name, b->name) == 0 &&
292 strcmp(a->authname, b->authname) == 0); 340 strcmp(a->authname, b->authname) == 0);
293} 341}
@@ -311,7 +359,8 @@ nametoid_show(struct seq_file *m, struct cache_detail *cd, struct cache_head *h)
311 return 0; 359 return 0;
312} 360}
313 361
314static struct ent *nametoid_lookup(struct ent *, int); 362static struct ent *nametoid_lookup(struct ent *);
363static struct ent *nametoid_update(struct ent *, struct ent *);
315static int nametoid_parse(struct cache_detail *, char *, int); 364static int nametoid_parse(struct cache_detail *, char *, int);
316 365
317static struct cache_detail nametoid_cache = { 366static struct cache_detail nametoid_cache = {
@@ -324,6 +373,10 @@ static struct cache_detail nametoid_cache = {
324 .cache_parse = nametoid_parse, 373 .cache_parse = nametoid_parse,
325 .cache_show = nametoid_show, 374 .cache_show = nametoid_show,
326 .warn_no_listener = warn_no_idmapd, 375 .warn_no_listener = warn_no_idmapd,
376 .match = nametoid_match,
377 .init = ent_init,
378 .update = ent_init,
379 .alloc = ent_alloc,
327}; 380};
328 381
329static int 382static int
@@ -373,7 +426,11 @@ nametoid_parse(struct cache_detail *cd, char *buf, int buflen)
373 set_bit(CACHE_NEGATIVE, &ent.h.flags); 426 set_bit(CACHE_NEGATIVE, &ent.h.flags);
374 427
375 error = -ENOMEM; 428 error = -ENOMEM;
376 if ((res = nametoid_lookup(&ent, 1)) == NULL) 429 res = nametoid_lookup(&ent);
430 if (res == NULL)
431 goto out;
432 res = nametoid_update(&ent, res);
433 if (res == NULL)
377 goto out; 434 goto out;
378 435
379 ent_put(&res->h, &nametoid_cache); 436 ent_put(&res->h, &nametoid_cache);
@@ -384,7 +441,30 @@ out:
384 return (error); 441 return (error);
385} 442}
386 443
387static DefineSimpleCacheLookup(ent, nametoid); 444
445static struct ent *
446nametoid_lookup(struct ent *item)
447{
448 struct cache_head *ch = sunrpc_cache_lookup(&nametoid_cache,
449 &item->h,
450 nametoid_hash(item));
451 if (ch)
452 return container_of(ch, struct ent, h);
453 else
454 return NULL;
455}
456
457static struct ent *
458nametoid_update(struct ent *new, struct ent *old)
459{
460 struct cache_head *ch = sunrpc_cache_update(&nametoid_cache,
461 &new->h, &old->h,
462 nametoid_hash(new));
463 if (ch)
464 return container_of(ch, struct ent, h);
465 else
466 return NULL;
467}
388 468
389/* 469/*
390 * Exported API 470 * Exported API
@@ -452,24 +532,24 @@ idmap_defer(struct cache_req *req)
452} 532}
453 533
454static inline int 534static inline int
455do_idmap_lookup(struct ent *(*lookup_fn)(struct ent *, int), struct ent *key, 535do_idmap_lookup(struct ent *(*lookup_fn)(struct ent *), struct ent *key,
456 struct cache_detail *detail, struct ent **item, 536 struct cache_detail *detail, struct ent **item,
457 struct idmap_defer_req *mdr) 537 struct idmap_defer_req *mdr)
458{ 538{
459 *item = lookup_fn(key, 0); 539 *item = lookup_fn(key);
460 if (!*item) 540 if (!*item)
461 return -ENOMEM; 541 return -ENOMEM;
462 return cache_check(detail, &(*item)->h, &mdr->req); 542 return cache_check(detail, &(*item)->h, &mdr->req);
463} 543}
464 544
465static inline int 545static inline int
466do_idmap_lookup_nowait(struct ent *(*lookup_fn)(struct ent *, int), 546do_idmap_lookup_nowait(struct ent *(*lookup_fn)(struct ent *),
467 struct ent *key, struct cache_detail *detail, 547 struct ent *key, struct cache_detail *detail,
468 struct ent **item) 548 struct ent **item)
469{ 549{
470 int ret = -ENOMEM; 550 int ret = -ENOMEM;
471 551
472 *item = lookup_fn(key, 0); 552 *item = lookup_fn(key);
473 if (!*item) 553 if (!*item)
474 goto out_err; 554 goto out_err;
475 ret = -ETIMEDOUT; 555 ret = -ETIMEDOUT;
@@ -490,7 +570,7 @@ out_err:
490 570
491static int 571static int
492idmap_lookup(struct svc_rqst *rqstp, 572idmap_lookup(struct svc_rqst *rqstp,
493 struct ent *(*lookup_fn)(struct ent *, int), struct ent *key, 573 struct ent *(*lookup_fn)(struct ent *), struct ent *key,
494 struct cache_detail *detail, struct ent **item) 574 struct cache_detail *detail, struct ent **item)
495{ 575{
496 struct idmap_defer_req *mdr; 576 struct idmap_defer_req *mdr;