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.c121
1 files changed, 19 insertions, 102 deletions
diff --git a/fs/nfsd/nfs4idmap.c b/fs/nfsd/nfs4idmap.c
index c78dbf493424..55780a22fdbd 100644
--- a/fs/nfsd/nfs4idmap.c
+++ b/fs/nfsd/nfs4idmap.c
@@ -33,10 +33,11 @@
33 */ 33 */
34 34
35#include <linux/module.h> 35#include <linux/module.h>
36#include <linux/nfsd_idmap.h>
37#include <linux/seq_file.h> 36#include <linux/seq_file.h>
38#include <linux/sched.h> 37#include <linux/sched.h>
39#include <linux/slab.h> 38#include <linux/slab.h>
39#include "idmap.h"
40#include "nfsd.h"
40 41
41/* 42/*
42 * Cache entry 43 * Cache entry
@@ -62,7 +63,6 @@ struct ent {
62 63
63#define ENT_HASHBITS 8 64#define ENT_HASHBITS 8
64#define ENT_HASHMAX (1 << ENT_HASHBITS) 65#define ENT_HASHMAX (1 << ENT_HASHBITS)
65#define ENT_HASHMASK (ENT_HASHMAX - 1)
66 66
67static void 67static void
68ent_init(struct cache_head *cnew, struct cache_head *citm) 68ent_init(struct cache_head *cnew, struct cache_head *citm)
@@ -482,109 +482,26 @@ nfsd_idmap_shutdown(void)
482 cache_unregister(&nametoid_cache); 482 cache_unregister(&nametoid_cache);
483} 483}
484 484
485/*
486 * Deferred request handling
487 */
488
489struct idmap_defer_req {
490 struct cache_req req;
491 struct cache_deferred_req deferred_req;
492 wait_queue_head_t waitq;
493 atomic_t count;
494};
495
496static inline void
497put_mdr(struct idmap_defer_req *mdr)
498{
499 if (atomic_dec_and_test(&mdr->count))
500 kfree(mdr);
501}
502
503static inline void
504get_mdr(struct idmap_defer_req *mdr)
505{
506 atomic_inc(&mdr->count);
507}
508
509static void
510idmap_revisit(struct cache_deferred_req *dreq, int toomany)
511{
512 struct idmap_defer_req *mdr =
513 container_of(dreq, struct idmap_defer_req, deferred_req);
514
515 wake_up(&mdr->waitq);
516 put_mdr(mdr);
517}
518
519static struct cache_deferred_req *
520idmap_defer(struct cache_req *req)
521{
522 struct idmap_defer_req *mdr =
523 container_of(req, struct idmap_defer_req, req);
524
525 mdr->deferred_req.revisit = idmap_revisit;
526 get_mdr(mdr);
527 return (&mdr->deferred_req);
528}
529
530static inline int
531do_idmap_lookup(struct ent *(*lookup_fn)(struct ent *), struct ent *key,
532 struct cache_detail *detail, struct ent **item,
533 struct idmap_defer_req *mdr)
534{
535 *item = lookup_fn(key);
536 if (!*item)
537 return -ENOMEM;
538 return cache_check(detail, &(*item)->h, &mdr->req);
539}
540
541static inline int
542do_idmap_lookup_nowait(struct ent *(*lookup_fn)(struct ent *),
543 struct ent *key, struct cache_detail *detail,
544 struct ent **item)
545{
546 int ret = -ENOMEM;
547
548 *item = lookup_fn(key);
549 if (!*item)
550 goto out_err;
551 ret = -ETIMEDOUT;
552 if (!test_bit(CACHE_VALID, &(*item)->h.flags)
553 || (*item)->h.expiry_time < get_seconds()
554 || detail->flush_time > (*item)->h.last_refresh)
555 goto out_put;
556 ret = -ENOENT;
557 if (test_bit(CACHE_NEGATIVE, &(*item)->h.flags))
558 goto out_put;
559 return 0;
560out_put:
561 cache_put(&(*item)->h, detail);
562out_err:
563 *item = NULL;
564 return ret;
565}
566
567static int 485static int
568idmap_lookup(struct svc_rqst *rqstp, 486idmap_lookup(struct svc_rqst *rqstp,
569 struct ent *(*lookup_fn)(struct ent *), struct ent *key, 487 struct ent *(*lookup_fn)(struct ent *), struct ent *key,
570 struct cache_detail *detail, struct ent **item) 488 struct cache_detail *detail, struct ent **item)
571{ 489{
572 struct idmap_defer_req *mdr;
573 int ret; 490 int ret;
574 491
575 mdr = kzalloc(sizeof(*mdr), GFP_KERNEL); 492 *item = lookup_fn(key);
576 if (!mdr) 493 if (!*item)
577 return -ENOMEM; 494 return -ENOMEM;
578 atomic_set(&mdr->count, 1); 495 retry:
579 init_waitqueue_head(&mdr->waitq); 496 ret = cache_check(detail, &(*item)->h, &rqstp->rq_chandle);
580 mdr->req.defer = idmap_defer; 497
581 ret = do_idmap_lookup(lookup_fn, key, detail, item, mdr); 498 if (ret == -ETIMEDOUT) {
582 if (ret == -EAGAIN) { 499 struct ent *prev_item = *item;
583 wait_event_interruptible_timeout(mdr->waitq, 500 *item = lookup_fn(key);
584 test_bit(CACHE_VALID, &(*item)->h.flags), 1 * HZ); 501 if (*item != prev_item)
585 ret = do_idmap_lookup_nowait(lookup_fn, key, detail, item); 502 goto retry;
503 cache_put(&(*item)->h, detail);
586 } 504 }
587 put_mdr(mdr);
588 return ret; 505 return ret;
589} 506}
590 507
@@ -597,7 +514,7 @@ rqst_authname(struct svc_rqst *rqstp)
597 return clp->name; 514 return clp->name;
598} 515}
599 516
600static int 517static __be32
601idmap_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen, 518idmap_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen,
602 uid_t *id) 519 uid_t *id)
603{ 520{
@@ -607,15 +524,15 @@ idmap_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen
607 int ret; 524 int ret;
608 525
609 if (namelen + 1 > sizeof(key.name)) 526 if (namelen + 1 > sizeof(key.name))
610 return -EINVAL; 527 return nfserr_badowner;
611 memcpy(key.name, name, namelen); 528 memcpy(key.name, name, namelen);
612 key.name[namelen] = '\0'; 529 key.name[namelen] = '\0';
613 strlcpy(key.authname, rqst_authname(rqstp), sizeof(key.authname)); 530 strlcpy(key.authname, rqst_authname(rqstp), sizeof(key.authname));
614 ret = idmap_lookup(rqstp, nametoid_lookup, &key, &nametoid_cache, &item); 531 ret = idmap_lookup(rqstp, nametoid_lookup, &key, &nametoid_cache, &item);
615 if (ret == -ENOENT) 532 if (ret == -ENOENT)
616 ret = -ESRCH; /* nfserr_badname */ 533 return nfserr_badowner;
617 if (ret) 534 if (ret)
618 return ret; 535 return nfserrno(ret);
619 *id = item->id; 536 *id = item->id;
620 cache_put(&item->h, &nametoid_cache); 537 cache_put(&item->h, &nametoid_cache);
621 return 0; 538 return 0;
@@ -643,14 +560,14 @@ idmap_id_to_name(struct svc_rqst *rqstp, int type, uid_t id, char *name)
643 return ret; 560 return ret;
644} 561}
645 562
646int 563__be32
647nfsd_map_name_to_uid(struct svc_rqst *rqstp, const char *name, size_t namelen, 564nfsd_map_name_to_uid(struct svc_rqst *rqstp, const char *name, size_t namelen,
648 __u32 *id) 565 __u32 *id)
649{ 566{
650 return idmap_name_to_id(rqstp, IDMAP_TYPE_USER, name, namelen, id); 567 return idmap_name_to_id(rqstp, IDMAP_TYPE_USER, name, namelen, id);
651} 568}
652 569
653int 570__be32
654nfsd_map_name_to_gid(struct svc_rqst *rqstp, const char *name, size_t namelen, 571nfsd_map_name_to_gid(struct svc_rqst *rqstp, const char *name, size_t namelen,
655 __u32 *id) 572 __u32 *id)
656{ 573{