aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2012-06-25 13:06:12 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2012-06-25 13:10:36 -0400
commit7b0cfee1a24efdfe0235bac62e53f686fe8a8e24 (patch)
treeeeeb8cc3bf7be5ec0e54b7c4f3808ef88ecca012 /fs/nfsd
parent9756fe38d10b2bf90c81dc4d2f17d5632e135364 (diff)
parent6b16351acbd415e66ba16bf7d473ece1574cf0bc (diff)
Merge tag 'v3.5-rc4' into drm-intel-next-queued
I want to merge the "no more fake agp on gen6+" patches into drm-intel-next (well, the last pieces). But a patch in 3.5-rc4 also adds a new use of dev->agp. Hence the backmarge to sort this out, for otherwise drm-intel-next merged into Linus' tree would conflict in the relevant code, things would compile but nicely OOPS at driver load :( Conflicts in this merge are just simple cases of "both branches changed/added lines at the same place". The only tricky part is to keep the order correct wrt the unwind code in case of errors in intel_ringbuffer.c (and the MI_DISPLAY_FLIP #defines in i915_reg.h together, obviously). Conflicts: drivers/gpu/drm/i915/i915_reg.h drivers/gpu/drm/i915/intel_ringbuffer.c Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'fs/nfsd')
-rw-r--r--fs/nfsd/auth.c2
-rw-r--r--fs/nfsd/export.c181
-rw-r--r--fs/nfsd/fault_inject.c1
-rw-r--r--fs/nfsd/idmap.h8
-rw-r--r--fs/nfsd/netns.h6
-rw-r--r--fs/nfsd/nfs4callback.c5
-rw-r--r--fs/nfsd/nfs4idmap.c113
-rw-r--r--fs/nfsd/nfs4recover.c4
-rw-r--r--fs/nfsd/nfs4state.c542
-rw-r--r--fs/nfsd/nfs4xdr.c62
-rw-r--r--fs/nfsd/nfsctl.c67
-rw-r--r--fs/nfsd/nfsfh.c2
-rw-r--r--fs/nfsd/nfssvc.c31
-rw-r--r--fs/nfsd/state.h1
-rw-r--r--fs/nfsd/vfs.c2
-rw-r--r--fs/nfsd/xdr4.h6
16 files changed, 569 insertions, 464 deletions
diff --git a/fs/nfsd/auth.c b/fs/nfsd/auth.c
index 204438cc914e..34a10d78b839 100644
--- a/fs/nfsd/auth.c
+++ b/fs/nfsd/auth.c
@@ -11,7 +11,7 @@ int nfsexp_flags(struct svc_rqst *rqstp, struct svc_export *exp)
11 struct exp_flavor_info *end = exp->ex_flavors + exp->ex_nflavors; 11 struct exp_flavor_info *end = exp->ex_flavors + exp->ex_nflavors;
12 12
13 for (f = exp->ex_flavors; f < end; f++) { 13 for (f = exp->ex_flavors; f < end; f++) {
14 if (f->pseudoflavor == rqstp->rq_flavor) 14 if (f->pseudoflavor == rqstp->rq_cred.cr_flavor)
15 return f->flags; 15 return f->flags;
16 } 16 }
17 return exp->ex_flags; 17 return exp->ex_flags;
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c
index 8e9689abbc0c..ba233499b9a5 100644
--- a/fs/nfsd/export.c
+++ b/fs/nfsd/export.c
@@ -15,11 +15,13 @@
15#include <linux/namei.h> 15#include <linux/namei.h>
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/exportfs.h> 17#include <linux/exportfs.h>
18#include <linux/sunrpc/svc_xprt.h>
18 19
19#include <net/ipv6.h> 20#include <net/ipv6.h>
20 21
21#include "nfsd.h" 22#include "nfsd.h"
22#include "nfsfh.h" 23#include "nfsfh.h"
24#include "netns.h"
23 25
24#define NFSDDBG_FACILITY NFSDDBG_EXPORT 26#define NFSDDBG_FACILITY NFSDDBG_EXPORT
25 27
@@ -38,7 +40,6 @@ typedef struct svc_export svc_export;
38#define EXPKEY_HASHBITS 8 40#define EXPKEY_HASHBITS 8
39#define EXPKEY_HASHMAX (1 << EXPKEY_HASHBITS) 41#define EXPKEY_HASHMAX (1 << EXPKEY_HASHBITS)
40#define EXPKEY_HASHMASK (EXPKEY_HASHMAX -1) 42#define EXPKEY_HASHMASK (EXPKEY_HASHMAX -1)
41static struct cache_head *expkey_table[EXPKEY_HASHMAX];
42 43
43static void expkey_put(struct kref *ref) 44static void expkey_put(struct kref *ref)
44{ 45{
@@ -71,9 +72,9 @@ static int expkey_upcall(struct cache_detail *cd, struct cache_head *h)
71 return sunrpc_cache_pipe_upcall(cd, h, expkey_request); 72 return sunrpc_cache_pipe_upcall(cd, h, expkey_request);
72} 73}
73 74
74static struct svc_expkey *svc_expkey_update(struct svc_expkey *new, struct svc_expkey *old); 75static struct svc_expkey *svc_expkey_update(struct cache_detail *cd, struct svc_expkey *new,
75static struct svc_expkey *svc_expkey_lookup(struct svc_expkey *); 76 struct svc_expkey *old);
76static struct cache_detail svc_expkey_cache; 77static struct svc_expkey *svc_expkey_lookup(struct cache_detail *cd, struct svc_expkey *);
77 78
78static int expkey_parse(struct cache_detail *cd, char *mesg, int mlen) 79static int expkey_parse(struct cache_detail *cd, char *mesg, int mlen)
79{ 80{
@@ -131,7 +132,7 @@ static int expkey_parse(struct cache_detail *cd, char *mesg, int mlen)
131 key.ek_fsidtype = fsidtype; 132 key.ek_fsidtype = fsidtype;
132 memcpy(key.ek_fsid, buf, len); 133 memcpy(key.ek_fsid, buf, len);
133 134
134 ek = svc_expkey_lookup(&key); 135 ek = svc_expkey_lookup(cd, &key);
135 err = -ENOMEM; 136 err = -ENOMEM;
136 if (!ek) 137 if (!ek)
137 goto out; 138 goto out;
@@ -145,7 +146,7 @@ static int expkey_parse(struct cache_detail *cd, char *mesg, int mlen)
145 err = 0; 146 err = 0;
146 if (len == 0) { 147 if (len == 0) {
147 set_bit(CACHE_NEGATIVE, &key.h.flags); 148 set_bit(CACHE_NEGATIVE, &key.h.flags);
148 ek = svc_expkey_update(&key, ek); 149 ek = svc_expkey_update(cd, &key, ek);
149 if (!ek) 150 if (!ek)
150 err = -ENOMEM; 151 err = -ENOMEM;
151 } else { 152 } else {
@@ -155,7 +156,7 @@ static int expkey_parse(struct cache_detail *cd, char *mesg, int mlen)
155 156
156 dprintk("Found the path %s\n", buf); 157 dprintk("Found the path %s\n", buf);
157 158
158 ek = svc_expkey_update(&key, ek); 159 ek = svc_expkey_update(cd, &key, ek);
159 if (!ek) 160 if (!ek)
160 err = -ENOMEM; 161 err = -ENOMEM;
161 path_put(&key.ek_path); 162 path_put(&key.ek_path);
@@ -163,7 +164,7 @@ static int expkey_parse(struct cache_detail *cd, char *mesg, int mlen)
163 cache_flush(); 164 cache_flush();
164 out: 165 out:
165 if (ek) 166 if (ek)
166 cache_put(&ek->h, &svc_expkey_cache); 167 cache_put(&ek->h, cd);
167 if (dom) 168 if (dom)
168 auth_domain_put(dom); 169 auth_domain_put(dom);
169 kfree(buf); 170 kfree(buf);
@@ -239,10 +240,9 @@ static struct cache_head *expkey_alloc(void)
239 return NULL; 240 return NULL;
240} 241}
241 242
242static struct cache_detail svc_expkey_cache = { 243static struct cache_detail svc_expkey_cache_template = {
243 .owner = THIS_MODULE, 244 .owner = THIS_MODULE,
244 .hash_size = EXPKEY_HASHMAX, 245 .hash_size = EXPKEY_HASHMAX,
245 .hash_table = expkey_table,
246 .name = "nfsd.fh", 246 .name = "nfsd.fh",
247 .cache_put = expkey_put, 247 .cache_put = expkey_put,
248 .cache_upcall = expkey_upcall, 248 .cache_upcall = expkey_upcall,
@@ -268,13 +268,12 @@ svc_expkey_hash(struct svc_expkey *item)
268} 268}
269 269
270static struct svc_expkey * 270static struct svc_expkey *
271svc_expkey_lookup(struct svc_expkey *item) 271svc_expkey_lookup(struct cache_detail *cd, struct svc_expkey *item)
272{ 272{
273 struct cache_head *ch; 273 struct cache_head *ch;
274 int hash = svc_expkey_hash(item); 274 int hash = svc_expkey_hash(item);
275 275
276 ch = sunrpc_cache_lookup(&svc_expkey_cache, &item->h, 276 ch = sunrpc_cache_lookup(cd, &item->h, hash);
277 hash);
278 if (ch) 277 if (ch)
279 return container_of(ch, struct svc_expkey, h); 278 return container_of(ch, struct svc_expkey, h);
280 else 279 else
@@ -282,13 +281,13 @@ svc_expkey_lookup(struct svc_expkey *item)
282} 281}
283 282
284static struct svc_expkey * 283static struct svc_expkey *
285svc_expkey_update(struct svc_expkey *new, struct svc_expkey *old) 284svc_expkey_update(struct cache_detail *cd, struct svc_expkey *new,
285 struct svc_expkey *old)
286{ 286{
287 struct cache_head *ch; 287 struct cache_head *ch;
288 int hash = svc_expkey_hash(new); 288 int hash = svc_expkey_hash(new);
289 289
290 ch = sunrpc_cache_update(&svc_expkey_cache, &new->h, 290 ch = sunrpc_cache_update(cd, &new->h, &old->h, hash);
291 &old->h, hash);
292 if (ch) 291 if (ch)
293 return container_of(ch, struct svc_expkey, h); 292 return container_of(ch, struct svc_expkey, h);
294 else 293 else
@@ -299,8 +298,6 @@ svc_expkey_update(struct svc_expkey *new, struct svc_expkey *old)
299#define EXPORT_HASHBITS 8 298#define EXPORT_HASHBITS 8
300#define EXPORT_HASHMAX (1<< EXPORT_HASHBITS) 299#define EXPORT_HASHMAX (1<< EXPORT_HASHBITS)
301 300
302static struct cache_head *export_table[EXPORT_HASHMAX];
303
304static void nfsd4_fslocs_free(struct nfsd4_fs_locations *fsloc) 301static void nfsd4_fslocs_free(struct nfsd4_fs_locations *fsloc)
305{ 302{
306 int i; 303 int i;
@@ -525,6 +522,7 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
525 goto out1; 522 goto out1;
526 523
527 exp.ex_client = dom; 524 exp.ex_client = dom;
525 exp.cd = cd;
528 526
529 /* expiry */ 527 /* expiry */
530 err = -EINVAL; 528 err = -EINVAL;
@@ -672,6 +670,7 @@ static void svc_export_init(struct cache_head *cnew, struct cache_head *citem)
672 new->ex_fslocs.locations = NULL; 670 new->ex_fslocs.locations = NULL;
673 new->ex_fslocs.locations_count = 0; 671 new->ex_fslocs.locations_count = 0;
674 new->ex_fslocs.migrated = 0; 672 new->ex_fslocs.migrated = 0;
673 new->cd = item->cd;
675} 674}
676 675
677static void export_update(struct cache_head *cnew, struct cache_head *citem) 676static void export_update(struct cache_head *cnew, struct cache_head *citem)
@@ -707,10 +706,9 @@ static struct cache_head *svc_export_alloc(void)
707 return NULL; 706 return NULL;
708} 707}
709 708
710struct cache_detail svc_export_cache = { 709static struct cache_detail svc_export_cache_template = {
711 .owner = THIS_MODULE, 710 .owner = THIS_MODULE,
712 .hash_size = EXPORT_HASHMAX, 711 .hash_size = EXPORT_HASHMAX,
713 .hash_table = export_table,
714 .name = "nfsd.export", 712 .name = "nfsd.export",
715 .cache_put = svc_export_put, 713 .cache_put = svc_export_put,
716 .cache_upcall = svc_export_upcall, 714 .cache_upcall = svc_export_upcall,
@@ -739,8 +737,7 @@ svc_export_lookup(struct svc_export *exp)
739 struct cache_head *ch; 737 struct cache_head *ch;
740 int hash = svc_export_hash(exp); 738 int hash = svc_export_hash(exp);
741 739
742 ch = sunrpc_cache_lookup(&svc_export_cache, &exp->h, 740 ch = sunrpc_cache_lookup(exp->cd, &exp->h, hash);
743 hash);
744 if (ch) 741 if (ch)
745 return container_of(ch, struct svc_export, h); 742 return container_of(ch, struct svc_export, h);
746 else 743 else
@@ -753,9 +750,7 @@ svc_export_update(struct svc_export *new, struct svc_export *old)
753 struct cache_head *ch; 750 struct cache_head *ch;
754 int hash = svc_export_hash(old); 751 int hash = svc_export_hash(old);
755 752
756 ch = sunrpc_cache_update(&svc_export_cache, &new->h, 753 ch = sunrpc_cache_update(old->cd, &new->h, &old->h, hash);
757 &old->h,
758 hash);
759 if (ch) 754 if (ch)
760 return container_of(ch, struct svc_export, h); 755 return container_of(ch, struct svc_export, h);
761 else 756 else
@@ -764,7 +759,8 @@ svc_export_update(struct svc_export *new, struct svc_export *old)
764 759
765 760
766static struct svc_expkey * 761static struct svc_expkey *
767exp_find_key(svc_client *clp, int fsid_type, u32 *fsidv, struct cache_req *reqp) 762exp_find_key(struct cache_detail *cd, svc_client *clp, int fsid_type,
763 u32 *fsidv, struct cache_req *reqp)
768{ 764{
769 struct svc_expkey key, *ek; 765 struct svc_expkey key, *ek;
770 int err; 766 int err;
@@ -776,18 +772,18 @@ exp_find_key(svc_client *clp, int fsid_type, u32 *fsidv, struct cache_req *reqp)
776 key.ek_fsidtype = fsid_type; 772 key.ek_fsidtype = fsid_type;
777 memcpy(key.ek_fsid, fsidv, key_len(fsid_type)); 773 memcpy(key.ek_fsid, fsidv, key_len(fsid_type));
778 774
779 ek = svc_expkey_lookup(&key); 775 ek = svc_expkey_lookup(cd, &key);
780 if (ek == NULL) 776 if (ek == NULL)
781 return ERR_PTR(-ENOMEM); 777 return ERR_PTR(-ENOMEM);
782 err = cache_check(&svc_expkey_cache, &ek->h, reqp); 778 err = cache_check(cd, &ek->h, reqp);
783 if (err) 779 if (err)
784 return ERR_PTR(err); 780 return ERR_PTR(err);
785 return ek; 781 return ek;
786} 782}
787 783
788 784
789static svc_export *exp_get_by_name(svc_client *clp, const struct path *path, 785static svc_export *exp_get_by_name(struct cache_detail *cd, svc_client *clp,
790 struct cache_req *reqp) 786 const struct path *path, struct cache_req *reqp)
791{ 787{
792 struct svc_export *exp, key; 788 struct svc_export *exp, key;
793 int err; 789 int err;
@@ -797,11 +793,12 @@ static svc_export *exp_get_by_name(svc_client *clp, const struct path *path,
797 793
798 key.ex_client = clp; 794 key.ex_client = clp;
799 key.ex_path = *path; 795 key.ex_path = *path;
796 key.cd = cd;
800 797
801 exp = svc_export_lookup(&key); 798 exp = svc_export_lookup(&key);
802 if (exp == NULL) 799 if (exp == NULL)
803 return ERR_PTR(-ENOMEM); 800 return ERR_PTR(-ENOMEM);
804 err = cache_check(&svc_export_cache, &exp->h, reqp); 801 err = cache_check(cd, &exp->h, reqp);
805 if (err) 802 if (err)
806 return ERR_PTR(err); 803 return ERR_PTR(err);
807 return exp; 804 return exp;
@@ -810,16 +807,17 @@ static svc_export *exp_get_by_name(svc_client *clp, const struct path *path,
810/* 807/*
811 * Find the export entry for a given dentry. 808 * Find the export entry for a given dentry.
812 */ 809 */
813static struct svc_export *exp_parent(svc_client *clp, struct path *path) 810static struct svc_export *exp_parent(struct cache_detail *cd, svc_client *clp,
811 struct path *path)
814{ 812{
815 struct dentry *saved = dget(path->dentry); 813 struct dentry *saved = dget(path->dentry);
816 svc_export *exp = exp_get_by_name(clp, path, NULL); 814 svc_export *exp = exp_get_by_name(cd, clp, path, NULL);
817 815
818 while (PTR_ERR(exp) == -ENOENT && !IS_ROOT(path->dentry)) { 816 while (PTR_ERR(exp) == -ENOENT && !IS_ROOT(path->dentry)) {
819 struct dentry *parent = dget_parent(path->dentry); 817 struct dentry *parent = dget_parent(path->dentry);
820 dput(path->dentry); 818 dput(path->dentry);
821 path->dentry = parent; 819 path->dentry = parent;
822 exp = exp_get_by_name(clp, path, NULL); 820 exp = exp_get_by_name(cd, clp, path, NULL);
823 } 821 }
824 dput(path->dentry); 822 dput(path->dentry);
825 path->dentry = saved; 823 path->dentry = saved;
@@ -834,13 +832,16 @@ static struct svc_export *exp_parent(svc_client *clp, struct path *path)
834 * since its harder to fool a kernel module than a user space program. 832 * since its harder to fool a kernel module than a user space program.
835 */ 833 */
836int 834int
837exp_rootfh(svc_client *clp, char *name, struct knfsd_fh *f, int maxsize) 835exp_rootfh(struct net *net, svc_client *clp, char *name,
836 struct knfsd_fh *f, int maxsize)
838{ 837{
839 struct svc_export *exp; 838 struct svc_export *exp;
840 struct path path; 839 struct path path;
841 struct inode *inode; 840 struct inode *inode;
842 struct svc_fh fh; 841 struct svc_fh fh;
843 int err; 842 int err;
843 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
844 struct cache_detail *cd = nn->svc_export_cache;
844 845
845 err = -EPERM; 846 err = -EPERM;
846 /* NB: we probably ought to check that it's NUL-terminated */ 847 /* NB: we probably ought to check that it's NUL-terminated */
@@ -853,7 +854,7 @@ exp_rootfh(svc_client *clp, char *name, struct knfsd_fh *f, int maxsize)
853 dprintk("nfsd: exp_rootfh(%s [%p] %s:%s/%ld)\n", 854 dprintk("nfsd: exp_rootfh(%s [%p] %s:%s/%ld)\n",
854 name, path.dentry, clp->name, 855 name, path.dentry, clp->name,
855 inode->i_sb->s_id, inode->i_ino); 856 inode->i_sb->s_id, inode->i_ino);
856 exp = exp_parent(clp, &path); 857 exp = exp_parent(cd, clp, &path);
857 if (IS_ERR(exp)) { 858 if (IS_ERR(exp)) {
858 err = PTR_ERR(exp); 859 err = PTR_ERR(exp);
859 goto out; 860 goto out;
@@ -875,16 +876,18 @@ out:
875 return err; 876 return err;
876} 877}
877 878
878static struct svc_export *exp_find(struct auth_domain *clp, int fsid_type, 879static struct svc_export *exp_find(struct cache_detail *cd,
880 struct auth_domain *clp, int fsid_type,
879 u32 *fsidv, struct cache_req *reqp) 881 u32 *fsidv, struct cache_req *reqp)
880{ 882{
881 struct svc_export *exp; 883 struct svc_export *exp;
882 struct svc_expkey *ek = exp_find_key(clp, fsid_type, fsidv, reqp); 884 struct nfsd_net *nn = net_generic(cd->net, nfsd_net_id);
885 struct svc_expkey *ek = exp_find_key(nn->svc_expkey_cache, clp, fsid_type, fsidv, reqp);
883 if (IS_ERR(ek)) 886 if (IS_ERR(ek))
884 return ERR_CAST(ek); 887 return ERR_CAST(ek);
885 888
886 exp = exp_get_by_name(clp, &ek->ek_path, reqp); 889 exp = exp_get_by_name(cd, clp, &ek->ek_path, reqp);
887 cache_put(&ek->h, &svc_expkey_cache); 890 cache_put(&ek->h, nn->svc_expkey_cache);
888 891
889 if (IS_ERR(exp)) 892 if (IS_ERR(exp))
890 return ERR_CAST(exp); 893 return ERR_CAST(exp);
@@ -901,13 +904,13 @@ __be32 check_nfsd_access(struct svc_export *exp, struct svc_rqst *rqstp)
901 return 0; 904 return 0;
902 /* ip-address based client; check sec= export option: */ 905 /* ip-address based client; check sec= export option: */
903 for (f = exp->ex_flavors; f < end; f++) { 906 for (f = exp->ex_flavors; f < end; f++) {
904 if (f->pseudoflavor == rqstp->rq_flavor) 907 if (f->pseudoflavor == rqstp->rq_cred.cr_flavor)
905 return 0; 908 return 0;
906 } 909 }
907 /* defaults in absence of sec= options: */ 910 /* defaults in absence of sec= options: */
908 if (exp->ex_nflavors == 0) { 911 if (exp->ex_nflavors == 0) {
909 if (rqstp->rq_flavor == RPC_AUTH_NULL || 912 if (rqstp->rq_cred.cr_flavor == RPC_AUTH_NULL ||
910 rqstp->rq_flavor == RPC_AUTH_UNIX) 913 rqstp->rq_cred.cr_flavor == RPC_AUTH_UNIX)
911 return 0; 914 return 0;
912 } 915 }
913 return nfserr_wrongsec; 916 return nfserr_wrongsec;
@@ -926,12 +929,14 @@ struct svc_export *
926rqst_exp_get_by_name(struct svc_rqst *rqstp, struct path *path) 929rqst_exp_get_by_name(struct svc_rqst *rqstp, struct path *path)
927{ 930{
928 struct svc_export *gssexp, *exp = ERR_PTR(-ENOENT); 931 struct svc_export *gssexp, *exp = ERR_PTR(-ENOENT);
932 struct nfsd_net *nn = net_generic(rqstp->rq_xprt->xpt_net, nfsd_net_id);
933 struct cache_detail *cd = nn->svc_export_cache;
929 934
930 if (rqstp->rq_client == NULL) 935 if (rqstp->rq_client == NULL)
931 goto gss; 936 goto gss;
932 937
933 /* First try the auth_unix client: */ 938 /* First try the auth_unix client: */
934 exp = exp_get_by_name(rqstp->rq_client, path, &rqstp->rq_chandle); 939 exp = exp_get_by_name(cd, rqstp->rq_client, path, &rqstp->rq_chandle);
935 if (PTR_ERR(exp) == -ENOENT) 940 if (PTR_ERR(exp) == -ENOENT)
936 goto gss; 941 goto gss;
937 if (IS_ERR(exp)) 942 if (IS_ERR(exp))
@@ -943,7 +948,7 @@ gss:
943 /* Otherwise, try falling back on gss client */ 948 /* Otherwise, try falling back on gss client */
944 if (rqstp->rq_gssclient == NULL) 949 if (rqstp->rq_gssclient == NULL)
945 return exp; 950 return exp;
946 gssexp = exp_get_by_name(rqstp->rq_gssclient, path, &rqstp->rq_chandle); 951 gssexp = exp_get_by_name(cd, rqstp->rq_gssclient, path, &rqstp->rq_chandle);
947 if (PTR_ERR(gssexp) == -ENOENT) 952 if (PTR_ERR(gssexp) == -ENOENT)
948 return exp; 953 return exp;
949 if (!IS_ERR(exp)) 954 if (!IS_ERR(exp))
@@ -955,12 +960,15 @@ struct svc_export *
955rqst_exp_find(struct svc_rqst *rqstp, int fsid_type, u32 *fsidv) 960rqst_exp_find(struct svc_rqst *rqstp, int fsid_type, u32 *fsidv)
956{ 961{
957 struct svc_export *gssexp, *exp = ERR_PTR(-ENOENT); 962 struct svc_export *gssexp, *exp = ERR_PTR(-ENOENT);
963 struct nfsd_net *nn = net_generic(rqstp->rq_xprt->xpt_net, nfsd_net_id);
964 struct cache_detail *cd = nn->svc_export_cache;
958 965
959 if (rqstp->rq_client == NULL) 966 if (rqstp->rq_client == NULL)
960 goto gss; 967 goto gss;
961 968
962 /* First try the auth_unix client: */ 969 /* First try the auth_unix client: */
963 exp = exp_find(rqstp->rq_client, fsid_type, fsidv, &rqstp->rq_chandle); 970 exp = exp_find(cd, rqstp->rq_client, fsid_type,
971 fsidv, &rqstp->rq_chandle);
964 if (PTR_ERR(exp) == -ENOENT) 972 if (PTR_ERR(exp) == -ENOENT)
965 goto gss; 973 goto gss;
966 if (IS_ERR(exp)) 974 if (IS_ERR(exp))
@@ -972,7 +980,7 @@ gss:
972 /* Otherwise, try falling back on gss client */ 980 /* Otherwise, try falling back on gss client */
973 if (rqstp->rq_gssclient == NULL) 981 if (rqstp->rq_gssclient == NULL)
974 return exp; 982 return exp;
975 gssexp = exp_find(rqstp->rq_gssclient, fsid_type, fsidv, 983 gssexp = exp_find(cd, rqstp->rq_gssclient, fsid_type, fsidv,
976 &rqstp->rq_chandle); 984 &rqstp->rq_chandle);
977 if (PTR_ERR(gssexp) == -ENOENT) 985 if (PTR_ERR(gssexp) == -ENOENT)
978 return exp; 986 return exp;
@@ -1029,13 +1037,15 @@ exp_pseudoroot(struct svc_rqst *rqstp, struct svc_fh *fhp)
1029/* Iterator */ 1037/* Iterator */
1030 1038
1031static void *e_start(struct seq_file *m, loff_t *pos) 1039static void *e_start(struct seq_file *m, loff_t *pos)
1032 __acquires(svc_export_cache.hash_lock) 1040 __acquires(((struct cache_detail *)m->private)->hash_lock)
1033{ 1041{
1034 loff_t n = *pos; 1042 loff_t n = *pos;
1035 unsigned hash, export; 1043 unsigned hash, export;
1036 struct cache_head *ch; 1044 struct cache_head *ch;
1037 1045 struct cache_detail *cd = m->private;
1038 read_lock(&svc_export_cache.hash_lock); 1046 struct cache_head **export_table = cd->hash_table;
1047
1048 read_lock(&cd->hash_lock);
1039 if (!n--) 1049 if (!n--)
1040 return SEQ_START_TOKEN; 1050 return SEQ_START_TOKEN;
1041 hash = n >> 32; 1051 hash = n >> 32;
@@ -1060,6 +1070,8 @@ static void *e_next(struct seq_file *m, void *p, loff_t *pos)
1060{ 1070{
1061 struct cache_head *ch = p; 1071 struct cache_head *ch = p;
1062 int hash = (*pos >> 32); 1072 int hash = (*pos >> 32);
1073 struct cache_detail *cd = m->private;
1074 struct cache_head **export_table = cd->hash_table;
1063 1075
1064 if (p == SEQ_START_TOKEN) 1076 if (p == SEQ_START_TOKEN)
1065 hash = 0; 1077 hash = 0;
@@ -1082,9 +1094,11 @@ static void *e_next(struct seq_file *m, void *p, loff_t *pos)
1082} 1094}
1083 1095
1084static void e_stop(struct seq_file *m, void *p) 1096static void e_stop(struct seq_file *m, void *p)
1085 __releases(svc_export_cache.hash_lock) 1097 __releases(((struct cache_detail *)m->private)->hash_lock)
1086{ 1098{
1087 read_unlock(&svc_export_cache.hash_lock); 1099 struct cache_detail *cd = m->private;
1100
1101 read_unlock(&cd->hash_lock);
1088} 1102}
1089 1103
1090static struct flags { 1104static struct flags {
@@ -1195,6 +1209,7 @@ static int e_show(struct seq_file *m, void *p)
1195{ 1209{
1196 struct cache_head *cp = p; 1210 struct cache_head *cp = p;
1197 struct svc_export *exp = container_of(cp, struct svc_export, h); 1211 struct svc_export *exp = container_of(cp, struct svc_export, h);
1212 struct cache_detail *cd = m->private;
1198 1213
1199 if (p == SEQ_START_TOKEN) { 1214 if (p == SEQ_START_TOKEN) {
1200 seq_puts(m, "# Version 1.1\n"); 1215 seq_puts(m, "# Version 1.1\n");
@@ -1203,10 +1218,10 @@ static int e_show(struct seq_file *m, void *p)
1203 } 1218 }
1204 1219
1205 cache_get(&exp->h); 1220 cache_get(&exp->h);
1206 if (cache_check(&svc_export_cache, &exp->h, NULL)) 1221 if (cache_check(cd, &exp->h, NULL))
1207 return 0; 1222 return 0;
1208 cache_put(&exp->h, &svc_export_cache); 1223 exp_put(exp);
1209 return svc_export_show(m, &svc_export_cache, cp); 1224 return svc_export_show(m, cd, cp);
1210} 1225}
1211 1226
1212const struct seq_operations nfs_exports_op = { 1227const struct seq_operations nfs_exports_op = {
@@ -1216,48 +1231,70 @@ const struct seq_operations nfs_exports_op = {
1216 .show = e_show, 1231 .show = e_show,
1217}; 1232};
1218 1233
1219
1220/* 1234/*
1221 * Initialize the exports module. 1235 * Initialize the exports module.
1222 */ 1236 */
1223int 1237int
1224nfsd_export_init(void) 1238nfsd_export_init(struct net *net)
1225{ 1239{
1226 int rv; 1240 int rv;
1227 dprintk("nfsd: initializing export module.\n"); 1241 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
1242
1243 dprintk("nfsd: initializing export module (net: %p).\n", net);
1228 1244
1229 rv = cache_register_net(&svc_export_cache, &init_net); 1245 nn->svc_export_cache = cache_create_net(&svc_export_cache_template, net);
1246 if (IS_ERR(nn->svc_export_cache))
1247 return PTR_ERR(nn->svc_export_cache);
1248 rv = cache_register_net(nn->svc_export_cache, net);
1230 if (rv) 1249 if (rv)
1231 return rv; 1250 goto destroy_export_cache;
1232 rv = cache_register_net(&svc_expkey_cache, &init_net); 1251
1252 nn->svc_expkey_cache = cache_create_net(&svc_expkey_cache_template, net);
1253 if (IS_ERR(nn->svc_expkey_cache)) {
1254 rv = PTR_ERR(nn->svc_expkey_cache);
1255 goto unregister_export_cache;
1256 }
1257 rv = cache_register_net(nn->svc_expkey_cache, net);
1233 if (rv) 1258 if (rv)
1234 cache_unregister_net(&svc_export_cache, &init_net); 1259 goto destroy_expkey_cache;
1235 return rv; 1260 return 0;
1236 1261
1262destroy_expkey_cache:
1263 cache_destroy_net(nn->svc_expkey_cache, net);
1264unregister_export_cache:
1265 cache_unregister_net(nn->svc_export_cache, net);
1266destroy_export_cache:
1267 cache_destroy_net(nn->svc_export_cache, net);
1268 return rv;
1237} 1269}
1238 1270
1239/* 1271/*
1240 * Flush exports table - called when last nfsd thread is killed 1272 * Flush exports table - called when last nfsd thread is killed
1241 */ 1273 */
1242void 1274void
1243nfsd_export_flush(void) 1275nfsd_export_flush(struct net *net)
1244{ 1276{
1245 cache_purge(&svc_expkey_cache); 1277 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
1246 cache_purge(&svc_export_cache); 1278
1279 cache_purge(nn->svc_expkey_cache);
1280 cache_purge(nn->svc_export_cache);
1247} 1281}
1248 1282
1249/* 1283/*
1250 * Shutdown the exports module. 1284 * Shutdown the exports module.
1251 */ 1285 */
1252void 1286void
1253nfsd_export_shutdown(void) 1287nfsd_export_shutdown(struct net *net)
1254{ 1288{
1289 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
1255 1290
1256 dprintk("nfsd: shutting down export module.\n"); 1291 dprintk("nfsd: shutting down export module (net: %p).\n", net);
1257 1292
1258 cache_unregister_net(&svc_expkey_cache, &init_net); 1293 cache_unregister_net(nn->svc_expkey_cache, net);
1259 cache_unregister_net(&svc_export_cache, &init_net); 1294 cache_unregister_net(nn->svc_export_cache, net);
1260 svcauth_unix_purge(); 1295 cache_destroy_net(nn->svc_expkey_cache, net);
1296 cache_destroy_net(nn->svc_export_cache, net);
1297 svcauth_unix_purge(net);
1261 1298
1262 dprintk("nfsd: export shutdown complete.\n"); 1299 dprintk("nfsd: export shutdown complete (net: %p).\n", net);
1263} 1300}
diff --git a/fs/nfsd/fault_inject.c b/fs/nfsd/fault_inject.c
index 9559ce468732..e6c38159622f 100644
--- a/fs/nfsd/fault_inject.c
+++ b/fs/nfsd/fault_inject.c
@@ -58,6 +58,7 @@ static int nfsd_inject_set(void *op_ptr, u64 val)
58 58
59static int nfsd_inject_get(void *data, u64 *val) 59static int nfsd_inject_get(void *data, u64 *val)
60{ 60{
61 *val = 0;
61 return 0; 62 return 0;
62} 63}
63 64
diff --git a/fs/nfsd/idmap.h b/fs/nfsd/idmap.h
index 2f3be1321534..9d513efc01ba 100644
--- a/fs/nfsd/idmap.h
+++ b/fs/nfsd/idmap.h
@@ -42,14 +42,14 @@
42#define IDMAP_NAMESZ 128 42#define IDMAP_NAMESZ 128
43 43
44#ifdef CONFIG_NFSD_V4 44#ifdef CONFIG_NFSD_V4
45int nfsd_idmap_init(void); 45int nfsd_idmap_init(struct net *);
46void nfsd_idmap_shutdown(void); 46void nfsd_idmap_shutdown(struct net *);
47#else 47#else
48static inline int nfsd_idmap_init(void) 48static inline int nfsd_idmap_init(struct net *net)
49{ 49{
50 return 0; 50 return 0;
51} 51}
52static inline void nfsd_idmap_shutdown(void) 52static inline void nfsd_idmap_shutdown(struct net *net)
53{ 53{
54} 54}
55#endif 55#endif
diff --git a/fs/nfsd/netns.h b/fs/nfsd/netns.h
index 12e0cff435b4..39365636b244 100644
--- a/fs/nfsd/netns.h
+++ b/fs/nfsd/netns.h
@@ -28,6 +28,12 @@ struct cld_net;
28 28
29struct nfsd_net { 29struct nfsd_net {
30 struct cld_net *cld_net; 30 struct cld_net *cld_net;
31
32 struct cache_detail *svc_expkey_cache;
33 struct cache_detail *svc_export_cache;
34
35 struct cache_detail *idtoname_cache;
36 struct cache_detail *nametoid_cache;
31}; 37};
32 38
33extern int nfsd_net_id; 39extern int nfsd_net_id;
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
index c8e9f637153a..a5fd6b982f27 100644
--- a/fs/nfsd/nfs4callback.c
+++ b/fs/nfsd/nfs4callback.c
@@ -650,9 +650,10 @@ static int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *c
650 struct rpc_clnt *client; 650 struct rpc_clnt *client;
651 651
652 if (clp->cl_minorversion == 0) { 652 if (clp->cl_minorversion == 0) {
653 if (!clp->cl_principal && (clp->cl_flavor >= RPC_AUTH_GSS_KRB5)) 653 if (!clp->cl_cred.cr_principal &&
654 (clp->cl_flavor >= RPC_AUTH_GSS_KRB5))
654 return -EINVAL; 655 return -EINVAL;
655 args.client_name = clp->cl_principal; 656 args.client_name = clp->cl_cred.cr_principal;
656 args.prognumber = conn->cb_prog, 657 args.prognumber = conn->cb_prog,
657 args.protocol = XPRT_TRANSPORT_TCP; 658 args.protocol = XPRT_TRANSPORT_TCP;
658 args.authflavor = clp->cl_flavor; 659 args.authflavor = clp->cl_flavor;
diff --git a/fs/nfsd/nfs4idmap.c b/fs/nfsd/nfs4idmap.c
index 322d11ce06a4..dae36f1dee95 100644
--- a/fs/nfsd/nfs4idmap.c
+++ b/fs/nfsd/nfs4idmap.c
@@ -36,9 +36,11 @@
36#include <linux/seq_file.h> 36#include <linux/seq_file.h>
37#include <linux/sched.h> 37#include <linux/sched.h>
38#include <linux/slab.h> 38#include <linux/slab.h>
39#include <linux/sunrpc/svc_xprt.h>
39#include <net/net_namespace.h> 40#include <net/net_namespace.h>
40#include "idmap.h" 41#include "idmap.h"
41#include "nfsd.h" 42#include "nfsd.h"
43#include "netns.h"
42 44
43/* 45/*
44 * Turn off idmapping when using AUTH_SYS. 46 * Turn off idmapping when using AUTH_SYS.
@@ -107,8 +109,6 @@ ent_alloc(void)
107 * ID -> Name cache 109 * ID -> Name cache
108 */ 110 */
109 111
110static struct cache_head *idtoname_table[ENT_HASHMAX];
111
112static uint32_t 112static uint32_t
113idtoname_hash(struct ent *ent) 113idtoname_hash(struct ent *ent)
114{ 114{
@@ -183,13 +183,13 @@ warn_no_idmapd(struct cache_detail *detail, int has_died)
183 183
184 184
185static int idtoname_parse(struct cache_detail *, char *, int); 185static int idtoname_parse(struct cache_detail *, char *, int);
186static struct ent *idtoname_lookup(struct ent *); 186static struct ent *idtoname_lookup(struct cache_detail *, struct ent *);
187static struct ent *idtoname_update(struct ent *, struct ent *); 187static struct ent *idtoname_update(struct cache_detail *, struct ent *,
188 struct ent *);
188 189
189static struct cache_detail idtoname_cache = { 190static struct cache_detail idtoname_cache_template = {
190 .owner = THIS_MODULE, 191 .owner = THIS_MODULE,
191 .hash_size = ENT_HASHMAX, 192 .hash_size = ENT_HASHMAX,
192 .hash_table = idtoname_table,
193 .name = "nfs4.idtoname", 193 .name = "nfs4.idtoname",
194 .cache_put = ent_put, 194 .cache_put = ent_put,
195 .cache_upcall = idtoname_upcall, 195 .cache_upcall = idtoname_upcall,
@@ -244,7 +244,7 @@ idtoname_parse(struct cache_detail *cd, char *buf, int buflen)
244 goto out; 244 goto out;
245 245
246 error = -ENOMEM; 246 error = -ENOMEM;
247 res = idtoname_lookup(&ent); 247 res = idtoname_lookup(cd, &ent);
248 if (!res) 248 if (!res)
249 goto out; 249 goto out;
250 250
@@ -260,11 +260,11 @@ idtoname_parse(struct cache_detail *cd, char *buf, int buflen)
260 else 260 else
261 memcpy(ent.name, buf1, sizeof(ent.name)); 261 memcpy(ent.name, buf1, sizeof(ent.name));
262 error = -ENOMEM; 262 error = -ENOMEM;
263 res = idtoname_update(&ent, res); 263 res = idtoname_update(cd, &ent, res);
264 if (res == NULL) 264 if (res == NULL)
265 goto out; 265 goto out;
266 266
267 cache_put(&res->h, &idtoname_cache); 267 cache_put(&res->h, cd);
268 268
269 error = 0; 269 error = 0;
270out: 270out:
@@ -275,10 +275,9 @@ out:
275 275
276 276
277static struct ent * 277static struct ent *
278idtoname_lookup(struct ent *item) 278idtoname_lookup(struct cache_detail *cd, struct ent *item)
279{ 279{
280 struct cache_head *ch = sunrpc_cache_lookup(&idtoname_cache, 280 struct cache_head *ch = sunrpc_cache_lookup(cd, &item->h,
281 &item->h,
282 idtoname_hash(item)); 281 idtoname_hash(item));
283 if (ch) 282 if (ch)
284 return container_of(ch, struct ent, h); 283 return container_of(ch, struct ent, h);
@@ -287,10 +286,9 @@ idtoname_lookup(struct ent *item)
287} 286}
288 287
289static struct ent * 288static struct ent *
290idtoname_update(struct ent *new, struct ent *old) 289idtoname_update(struct cache_detail *cd, struct ent *new, struct ent *old)
291{ 290{
292 struct cache_head *ch = sunrpc_cache_update(&idtoname_cache, 291 struct cache_head *ch = sunrpc_cache_update(cd, &new->h, &old->h,
293 &new->h, &old->h,
294 idtoname_hash(new)); 292 idtoname_hash(new));
295 if (ch) 293 if (ch)
296 return container_of(ch, struct ent, h); 294 return container_of(ch, struct ent, h);
@@ -303,8 +301,6 @@ idtoname_update(struct ent *new, struct ent *old)
303 * Name -> ID cache 301 * Name -> ID cache
304 */ 302 */
305 303
306static struct cache_head *nametoid_table[ENT_HASHMAX];
307
308static inline int 304static inline int
309nametoid_hash(struct ent *ent) 305nametoid_hash(struct ent *ent)
310{ 306{
@@ -359,14 +355,14 @@ nametoid_show(struct seq_file *m, struct cache_detail *cd, struct cache_head *h)
359 return 0; 355 return 0;
360} 356}
361 357
362static struct ent *nametoid_lookup(struct ent *); 358static struct ent *nametoid_lookup(struct cache_detail *, struct ent *);
363static struct ent *nametoid_update(struct ent *, struct ent *); 359static struct ent *nametoid_update(struct cache_detail *, struct ent *,
360 struct ent *);
364static int nametoid_parse(struct cache_detail *, char *, int); 361static int nametoid_parse(struct cache_detail *, char *, int);
365 362
366static struct cache_detail nametoid_cache = { 363static struct cache_detail nametoid_cache_template = {
367 .owner = THIS_MODULE, 364 .owner = THIS_MODULE,
368 .hash_size = ENT_HASHMAX, 365 .hash_size = ENT_HASHMAX,
369 .hash_table = nametoid_table,
370 .name = "nfs4.nametoid", 366 .name = "nfs4.nametoid",
371 .cache_put = ent_put, 367 .cache_put = ent_put,
372 .cache_upcall = nametoid_upcall, 368 .cache_upcall = nametoid_upcall,
@@ -426,14 +422,14 @@ nametoid_parse(struct cache_detail *cd, char *buf, int buflen)
426 set_bit(CACHE_NEGATIVE, &ent.h.flags); 422 set_bit(CACHE_NEGATIVE, &ent.h.flags);
427 423
428 error = -ENOMEM; 424 error = -ENOMEM;
429 res = nametoid_lookup(&ent); 425 res = nametoid_lookup(cd, &ent);
430 if (res == NULL) 426 if (res == NULL)
431 goto out; 427 goto out;
432 res = nametoid_update(&ent, res); 428 res = nametoid_update(cd, &ent, res);
433 if (res == NULL) 429 if (res == NULL)
434 goto out; 430 goto out;
435 431
436 cache_put(&res->h, &nametoid_cache); 432 cache_put(&res->h, cd);
437 error = 0; 433 error = 0;
438out: 434out:
439 kfree(buf1); 435 kfree(buf1);
@@ -443,10 +439,9 @@ out:
443 439
444 440
445static struct ent * 441static struct ent *
446nametoid_lookup(struct ent *item) 442nametoid_lookup(struct cache_detail *cd, struct ent *item)
447{ 443{
448 struct cache_head *ch = sunrpc_cache_lookup(&nametoid_cache, 444 struct cache_head *ch = sunrpc_cache_lookup(cd, &item->h,
449 &item->h,
450 nametoid_hash(item)); 445 nametoid_hash(item));
451 if (ch) 446 if (ch)
452 return container_of(ch, struct ent, h); 447 return container_of(ch, struct ent, h);
@@ -455,10 +450,9 @@ nametoid_lookup(struct ent *item)
455} 450}
456 451
457static struct ent * 452static struct ent *
458nametoid_update(struct ent *new, struct ent *old) 453nametoid_update(struct cache_detail *cd, struct ent *new, struct ent *old)
459{ 454{
460 struct cache_head *ch = sunrpc_cache_update(&nametoid_cache, 455 struct cache_head *ch = sunrpc_cache_update(cd, &new->h, &old->h,
461 &new->h, &old->h,
462 nametoid_hash(new)); 456 nametoid_hash(new));
463 if (ch) 457 if (ch)
464 return container_of(ch, struct ent, h); 458 return container_of(ch, struct ent, h);
@@ -471,34 +465,55 @@ nametoid_update(struct ent *new, struct ent *old)
471 */ 465 */
472 466
473int 467int
474nfsd_idmap_init(void) 468nfsd_idmap_init(struct net *net)
475{ 469{
476 int rv; 470 int rv;
471 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
477 472
478 rv = cache_register_net(&idtoname_cache, &init_net); 473 nn->idtoname_cache = cache_create_net(&idtoname_cache_template, net);
474 if (IS_ERR(nn->idtoname_cache))
475 return PTR_ERR(nn->idtoname_cache);
476 rv = cache_register_net(nn->idtoname_cache, net);
479 if (rv) 477 if (rv)
480 return rv; 478 goto destroy_idtoname_cache;
481 rv = cache_register_net(&nametoid_cache, &init_net); 479 nn->nametoid_cache = cache_create_net(&nametoid_cache_template, net);
480 if (IS_ERR(nn->nametoid_cache)) {
481 rv = PTR_ERR(nn->idtoname_cache);
482 goto unregister_idtoname_cache;
483 }
484 rv = cache_register_net(nn->nametoid_cache, net);
482 if (rv) 485 if (rv)
483 cache_unregister_net(&idtoname_cache, &init_net); 486 goto destroy_nametoid_cache;
487 return 0;
488
489destroy_nametoid_cache:
490 cache_destroy_net(nn->nametoid_cache, net);
491unregister_idtoname_cache:
492 cache_unregister_net(nn->idtoname_cache, net);
493destroy_idtoname_cache:
494 cache_destroy_net(nn->idtoname_cache, net);
484 return rv; 495 return rv;
485} 496}
486 497
487void 498void
488nfsd_idmap_shutdown(void) 499nfsd_idmap_shutdown(struct net *net)
489{ 500{
490 cache_unregister_net(&idtoname_cache, &init_net); 501 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
491 cache_unregister_net(&nametoid_cache, &init_net); 502
503 cache_unregister_net(nn->idtoname_cache, net);
504 cache_unregister_net(nn->nametoid_cache, net);
505 cache_destroy_net(nn->idtoname_cache, net);
506 cache_destroy_net(nn->nametoid_cache, net);
492} 507}
493 508
494static int 509static int
495idmap_lookup(struct svc_rqst *rqstp, 510idmap_lookup(struct svc_rqst *rqstp,
496 struct ent *(*lookup_fn)(struct ent *), struct ent *key, 511 struct ent *(*lookup_fn)(struct cache_detail *, struct ent *),
497 struct cache_detail *detail, struct ent **item) 512 struct ent *key, struct cache_detail *detail, struct ent **item)
498{ 513{
499 int ret; 514 int ret;
500 515
501 *item = lookup_fn(key); 516 *item = lookup_fn(detail, key);
502 if (!*item) 517 if (!*item)
503 return -ENOMEM; 518 return -ENOMEM;
504 retry: 519 retry:
@@ -506,7 +521,7 @@ idmap_lookup(struct svc_rqst *rqstp,
506 521
507 if (ret == -ETIMEDOUT) { 522 if (ret == -ETIMEDOUT) {
508 struct ent *prev_item = *item; 523 struct ent *prev_item = *item;
509 *item = lookup_fn(key); 524 *item = lookup_fn(detail, key);
510 if (*item != prev_item) 525 if (*item != prev_item)
511 goto retry; 526 goto retry;
512 cache_put(&(*item)->h, detail); 527 cache_put(&(*item)->h, detail);
@@ -531,19 +546,20 @@ idmap_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen
531 .type = type, 546 .type = type,
532 }; 547 };
533 int ret; 548 int ret;
549 struct nfsd_net *nn = net_generic(rqstp->rq_xprt->xpt_net, nfsd_net_id);
534 550
535 if (namelen + 1 > sizeof(key.name)) 551 if (namelen + 1 > sizeof(key.name))
536 return nfserr_badowner; 552 return nfserr_badowner;
537 memcpy(key.name, name, namelen); 553 memcpy(key.name, name, namelen);
538 key.name[namelen] = '\0'; 554 key.name[namelen] = '\0';
539 strlcpy(key.authname, rqst_authname(rqstp), sizeof(key.authname)); 555 strlcpy(key.authname, rqst_authname(rqstp), sizeof(key.authname));
540 ret = idmap_lookup(rqstp, nametoid_lookup, &key, &nametoid_cache, &item); 556 ret = idmap_lookup(rqstp, nametoid_lookup, &key, nn->nametoid_cache, &item);
541 if (ret == -ENOENT) 557 if (ret == -ENOENT)
542 return nfserr_badowner; 558 return nfserr_badowner;
543 if (ret) 559 if (ret)
544 return nfserrno(ret); 560 return nfserrno(ret);
545 *id = item->id; 561 *id = item->id;
546 cache_put(&item->h, &nametoid_cache); 562 cache_put(&item->h, nn->nametoid_cache);
547 return 0; 563 return 0;
548} 564}
549 565
@@ -555,9 +571,10 @@ idmap_id_to_name(struct svc_rqst *rqstp, int type, uid_t id, char *name)
555 .type = type, 571 .type = type,
556 }; 572 };
557 int ret; 573 int ret;
574 struct nfsd_net *nn = net_generic(rqstp->rq_xprt->xpt_net, nfsd_net_id);
558 575
559 strlcpy(key.authname, rqst_authname(rqstp), sizeof(key.authname)); 576 strlcpy(key.authname, rqst_authname(rqstp), sizeof(key.authname));
560 ret = idmap_lookup(rqstp, idtoname_lookup, &key, &idtoname_cache, &item); 577 ret = idmap_lookup(rqstp, idtoname_lookup, &key, nn->idtoname_cache, &item);
561 if (ret == -ENOENT) 578 if (ret == -ENOENT)
562 return sprintf(name, "%u", id); 579 return sprintf(name, "%u", id);
563 if (ret) 580 if (ret)
@@ -565,7 +582,7 @@ idmap_id_to_name(struct svc_rqst *rqstp, int type, uid_t id, char *name)
565 ret = strlen(item->name); 582 ret = strlen(item->name);
566 BUG_ON(ret > IDMAP_NAMESZ); 583 BUG_ON(ret > IDMAP_NAMESZ);
567 memcpy(name, item->name, ret); 584 memcpy(name, item->name, ret);
568 cache_put(&item->h, &idtoname_cache); 585 cache_put(&item->h, nn->idtoname_cache);
569 return ret; 586 return ret;
570} 587}
571 588
@@ -588,7 +605,7 @@ numeric_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namel
588static __be32 605static __be32
589do_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen, uid_t *id) 606do_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen, uid_t *id)
590{ 607{
591 if (nfs4_disable_idmapping && rqstp->rq_flavor < RPC_AUTH_GSS) 608 if (nfs4_disable_idmapping && rqstp->rq_cred.cr_flavor < RPC_AUTH_GSS)
592 if (numeric_name_to_id(rqstp, type, name, namelen, id)) 609 if (numeric_name_to_id(rqstp, type, name, namelen, id))
593 return 0; 610 return 0;
594 /* 611 /*
@@ -601,7 +618,7 @@ do_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen, u
601static int 618static int
602do_id_to_name(struct svc_rqst *rqstp, int type, uid_t id, char *name) 619do_id_to_name(struct svc_rqst *rqstp, int type, uid_t id, char *name)
603{ 620{
604 if (nfs4_disable_idmapping && rqstp->rq_flavor < RPC_AUTH_GSS) 621 if (nfs4_disable_idmapping && rqstp->rq_cred.cr_flavor < RPC_AUTH_GSS)
605 return sprintf(name, "%u", id); 622 return sprintf(name, "%u", id);
606 return idmap_id_to_name(rqstp, type, id, name); 623 return idmap_id_to_name(rqstp, type, id, name);
607} 624}
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
index ed3f9206a0ee..5ff0b7b9fc08 100644
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -570,7 +570,7 @@ static ssize_t
570cld_pipe_downcall(struct file *filp, const char __user *src, size_t mlen) 570cld_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
571{ 571{
572 struct cld_upcall *tmp, *cup; 572 struct cld_upcall *tmp, *cup;
573 struct cld_msg *cmsg = (struct cld_msg *)src; 573 struct cld_msg __user *cmsg = (struct cld_msg __user *)src;
574 uint32_t xid; 574 uint32_t xid;
575 struct nfsd_net *nn = net_generic(filp->f_dentry->d_sb->s_fs_info, 575 struct nfsd_net *nn = net_generic(filp->f_dentry->d_sb->s_fs_info,
576 nfsd_net_id); 576 nfsd_net_id);
@@ -1029,7 +1029,7 @@ rpc_pipefs_event(struct notifier_block *nb, unsigned long event, void *ptr)
1029 return ret; 1029 return ret;
1030} 1030}
1031 1031
1032struct notifier_block nfsd4_cld_block = { 1032static struct notifier_block nfsd4_cld_block = {
1033 .notifier_call = rpc_pipefs_event, 1033 .notifier_call = rpc_pipefs_event,
1034}; 1034};
1035 1035
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 7f71c69cdcdf..94effd5bc4a1 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -42,6 +42,7 @@
42#include <linux/sunrpc/clnt.h> 42#include <linux/sunrpc/clnt.h>
43#include "xdr4.h" 43#include "xdr4.h"
44#include "vfs.h" 44#include "vfs.h"
45#include "current_stateid.h"
45 46
46#define NFSDDBG_FACILITY NFSDDBG_PROC 47#define NFSDDBG_FACILITY NFSDDBG_PROC
47 48
@@ -447,37 +448,69 @@ static struct list_head close_lru;
447 * 448 *
448 * which we should reject. 449 * which we should reject.
449 */ 450 */
450static void 451static unsigned int
451set_access(unsigned int *access, unsigned long bmap) { 452bmap_to_share_mode(unsigned long bmap) {
452 int i; 453 int i;
454 unsigned int access = 0;
453 455
454 *access = 0;
455 for (i = 1; i < 4; i++) { 456 for (i = 1; i < 4; i++) {
456 if (test_bit(i, &bmap)) 457 if (test_bit(i, &bmap))
457 *access |= i; 458 access |= i;
458 }
459}
460
461static void
462set_deny(unsigned int *deny, unsigned long bmap) {
463 int i;
464
465 *deny = 0;
466 for (i = 0; i < 4; i++) {
467 if (test_bit(i, &bmap))
468 *deny |= i ;
469 } 459 }
460 return access;
470} 461}
471 462
472static int 463static bool
473test_share(struct nfs4_ol_stateid *stp, struct nfsd4_open *open) { 464test_share(struct nfs4_ol_stateid *stp, struct nfsd4_open *open) {
474 unsigned int access, deny; 465 unsigned int access, deny;
475 466
476 set_access(&access, stp->st_access_bmap); 467 access = bmap_to_share_mode(stp->st_access_bmap);
477 set_deny(&deny, stp->st_deny_bmap); 468 deny = bmap_to_share_mode(stp->st_deny_bmap);
478 if ((access & open->op_share_deny) || (deny & open->op_share_access)) 469 if ((access & open->op_share_deny) || (deny & open->op_share_access))
479 return 0; 470 return false;
480 return 1; 471 return true;
472}
473
474/* set share access for a given stateid */
475static inline void
476set_access(u32 access, struct nfs4_ol_stateid *stp)
477{
478 __set_bit(access, &stp->st_access_bmap);
479}
480
481/* clear share access for a given stateid */
482static inline void
483clear_access(u32 access, struct nfs4_ol_stateid *stp)
484{
485 __clear_bit(access, &stp->st_access_bmap);
486}
487
488/* test whether a given stateid has access */
489static inline bool
490test_access(u32 access, struct nfs4_ol_stateid *stp)
491{
492 return test_bit(access, &stp->st_access_bmap);
493}
494
495/* set share deny for a given stateid */
496static inline void
497set_deny(u32 access, struct nfs4_ol_stateid *stp)
498{
499 __set_bit(access, &stp->st_deny_bmap);
500}
501
502/* clear share deny for a given stateid */
503static inline void
504clear_deny(u32 access, struct nfs4_ol_stateid *stp)
505{
506 __clear_bit(access, &stp->st_deny_bmap);
507}
508
509/* test whether a given stateid is denying specific access */
510static inline bool
511test_deny(u32 access, struct nfs4_ol_stateid *stp)
512{
513 return test_bit(access, &stp->st_deny_bmap);
481} 514}
482 515
483static int nfs4_access_to_omode(u32 access) 516static int nfs4_access_to_omode(u32 access)
@@ -493,6 +526,20 @@ static int nfs4_access_to_omode(u32 access)
493 BUG(); 526 BUG();
494} 527}
495 528
529/* release all access and file references for a given stateid */
530static void
531release_all_access(struct nfs4_ol_stateid *stp)
532{
533 int i;
534
535 for (i = 1; i < 4; i++) {
536 if (test_access(i, stp))
537 nfs4_file_put_access(stp->st_file,
538 nfs4_access_to_omode(i));
539 clear_access(i, stp);
540 }
541}
542
496static void unhash_generic_stateid(struct nfs4_ol_stateid *stp) 543static void unhash_generic_stateid(struct nfs4_ol_stateid *stp)
497{ 544{
498 list_del(&stp->st_perfile); 545 list_del(&stp->st_perfile);
@@ -501,16 +548,7 @@ static void unhash_generic_stateid(struct nfs4_ol_stateid *stp)
501 548
502static void close_generic_stateid(struct nfs4_ol_stateid *stp) 549static void close_generic_stateid(struct nfs4_ol_stateid *stp)
503{ 550{
504 int i; 551 release_all_access(stp);
505
506 if (stp->st_access_bmap) {
507 for (i = 1; i < 4; i++) {
508 if (test_bit(i, &stp->st_access_bmap))
509 nfs4_file_put_access(stp->st_file,
510 nfs4_access_to_omode(i));
511 __clear_bit(i, &stp->st_access_bmap);
512 }
513 }
514 put_nfs4_file(stp->st_file); 552 put_nfs4_file(stp->st_file);
515 stp->st_file = NULL; 553 stp->st_file = NULL;
516} 554}
@@ -862,7 +900,7 @@ static void free_session(struct kref *kref)
862 struct nfsd4_session *ses; 900 struct nfsd4_session *ses;
863 int mem; 901 int mem;
864 902
865 BUG_ON(!spin_is_locked(&client_lock)); 903 lockdep_assert_held(&client_lock);
866 ses = container_of(kref, struct nfsd4_session, se_ref); 904 ses = container_of(kref, struct nfsd4_session, se_ref);
867 nfsd4_del_conns(ses); 905 nfsd4_del_conns(ses);
868 spin_lock(&nfsd_drc_lock); 906 spin_lock(&nfsd_drc_lock);
@@ -885,7 +923,7 @@ static struct nfsd4_session *alloc_init_session(struct svc_rqst *rqstp, struct n
885 struct nfsd4_session *new; 923 struct nfsd4_session *new;
886 struct nfsd4_channel_attrs *fchan = &cses->fore_channel; 924 struct nfsd4_channel_attrs *fchan = &cses->fore_channel;
887 int numslots, slotsize; 925 int numslots, slotsize;
888 int status; 926 __be32 status;
889 int idx; 927 int idx;
890 928
891 /* 929 /*
@@ -984,7 +1022,8 @@ static inline void
984renew_client_locked(struct nfs4_client *clp) 1022renew_client_locked(struct nfs4_client *clp)
985{ 1023{
986 if (is_client_expired(clp)) { 1024 if (is_client_expired(clp)) {
987 dprintk("%s: client (clientid %08x/%08x) already expired\n", 1025 WARN_ON(1);
1026 printk("%s: client (clientid %08x/%08x) already expired\n",
988 __func__, 1027 __func__,
989 clp->cl_clientid.cl_boot, 1028 clp->cl_clientid.cl_boot,
990 clp->cl_clientid.cl_id); 1029 clp->cl_clientid.cl_id);
@@ -1041,7 +1080,7 @@ static struct nfs4_client *alloc_client(struct xdr_netobj name)
1041static inline void 1080static inline void
1042free_client(struct nfs4_client *clp) 1081free_client(struct nfs4_client *clp)
1043{ 1082{
1044 BUG_ON(!spin_is_locked(&client_lock)); 1083 lockdep_assert_held(&client_lock);
1045 while (!list_empty(&clp->cl_sessions)) { 1084 while (!list_empty(&clp->cl_sessions)) {
1046 struct nfsd4_session *ses; 1085 struct nfsd4_session *ses;
1047 ses = list_entry(clp->cl_sessions.next, struct nfsd4_session, 1086 ses = list_entry(clp->cl_sessions.next, struct nfsd4_session,
@@ -1049,9 +1088,7 @@ free_client(struct nfs4_client *clp)
1049 list_del(&ses->se_perclnt); 1088 list_del(&ses->se_perclnt);
1050 nfsd4_put_session_locked(ses); 1089 nfsd4_put_session_locked(ses);
1051 } 1090 }
1052 if (clp->cl_cred.cr_group_info) 1091 free_svc_cred(&clp->cl_cred);
1053 put_group_info(clp->cl_cred.cr_group_info);
1054 kfree(clp->cl_principal);
1055 kfree(clp->cl_name.data); 1092 kfree(clp->cl_name.data);
1056 kfree(clp); 1093 kfree(clp);
1057} 1094}
@@ -1132,12 +1169,21 @@ static void copy_clid(struct nfs4_client *target, struct nfs4_client *source)
1132 target->cl_clientid.cl_id = source->cl_clientid.cl_id; 1169 target->cl_clientid.cl_id = source->cl_clientid.cl_id;
1133} 1170}
1134 1171
1135static void copy_cred(struct svc_cred *target, struct svc_cred *source) 1172static int copy_cred(struct svc_cred *target, struct svc_cred *source)
1136{ 1173{
1174 if (source->cr_principal) {
1175 target->cr_principal =
1176 kstrdup(source->cr_principal, GFP_KERNEL);
1177 if (target->cr_principal == NULL)
1178 return -ENOMEM;
1179 } else
1180 target->cr_principal = NULL;
1181 target->cr_flavor = source->cr_flavor;
1137 target->cr_uid = source->cr_uid; 1182 target->cr_uid = source->cr_uid;
1138 target->cr_gid = source->cr_gid; 1183 target->cr_gid = source->cr_gid;
1139 target->cr_group_info = source->cr_group_info; 1184 target->cr_group_info = source->cr_group_info;
1140 get_group_info(target->cr_group_info); 1185 get_group_info(target->cr_group_info);
1186 return 0;
1141} 1187}
1142 1188
1143static int same_name(const char *n1, const char *n2) 1189static int same_name(const char *n1, const char *n2)
@@ -1157,11 +1203,31 @@ same_clid(clientid_t *cl1, clientid_t *cl2)
1157 return (cl1->cl_boot == cl2->cl_boot) && (cl1->cl_id == cl2->cl_id); 1203 return (cl1->cl_boot == cl2->cl_boot) && (cl1->cl_id == cl2->cl_id);
1158} 1204}
1159 1205
1160/* XXX what about NGROUP */ 1206static bool groups_equal(struct group_info *g1, struct group_info *g2)
1207{
1208 int i;
1209
1210 if (g1->ngroups != g2->ngroups)
1211 return false;
1212 for (i=0; i<g1->ngroups; i++)
1213 if (GROUP_AT(g1, i) != GROUP_AT(g2, i))
1214 return false;
1215 return true;
1216}
1217
1161static int 1218static int
1162same_creds(struct svc_cred *cr1, struct svc_cred *cr2) 1219same_creds(struct svc_cred *cr1, struct svc_cred *cr2)
1163{ 1220{
1164 return cr1->cr_uid == cr2->cr_uid; 1221 if ((cr1->cr_flavor != cr2->cr_flavor)
1222 || (cr1->cr_uid != cr2->cr_uid)
1223 || (cr1->cr_gid != cr2->cr_gid)
1224 || !groups_equal(cr1->cr_group_info, cr2->cr_group_info))
1225 return false;
1226 if (cr1->cr_principal == cr2->cr_principal)
1227 return true;
1228 if (!cr1->cr_principal || !cr2->cr_principal)
1229 return false;
1230 return 0 == strcmp(cr1->cr_principal, cr1->cr_principal);
1165} 1231}
1166 1232
1167static void gen_clid(struct nfs4_client *clp) 1233static void gen_clid(struct nfs4_client *clp)
@@ -1204,25 +1270,20 @@ static struct nfs4_client *create_client(struct xdr_netobj name, char *recdir,
1204{ 1270{
1205 struct nfs4_client *clp; 1271 struct nfs4_client *clp;
1206 struct sockaddr *sa = svc_addr(rqstp); 1272 struct sockaddr *sa = svc_addr(rqstp);
1207 char *princ; 1273 int ret;
1208 1274
1209 clp = alloc_client(name); 1275 clp = alloc_client(name);
1210 if (clp == NULL) 1276 if (clp == NULL)
1211 return NULL; 1277 return NULL;
1212 1278
1213 INIT_LIST_HEAD(&clp->cl_sessions); 1279 INIT_LIST_HEAD(&clp->cl_sessions);
1214 1280 ret = copy_cred(&clp->cl_cred, &rqstp->rq_cred);
1215 princ = svc_gss_principal(rqstp); 1281 if (ret) {
1216 if (princ) { 1282 spin_lock(&client_lock);
1217 clp->cl_principal = kstrdup(princ, GFP_KERNEL); 1283 free_client(clp);
1218 if (clp->cl_principal == NULL) { 1284 spin_unlock(&client_lock);
1219 spin_lock(&client_lock); 1285 return NULL;
1220 free_client(clp);
1221 spin_unlock(&client_lock);
1222 return NULL;
1223 }
1224 } 1286 }
1225
1226 idr_init(&clp->cl_stateids); 1287 idr_init(&clp->cl_stateids);
1227 memcpy(clp->cl_recdir, recdir, HEXDIR_LEN); 1288 memcpy(clp->cl_recdir, recdir, HEXDIR_LEN);
1228 atomic_set(&clp->cl_refcount, 0); 1289 atomic_set(&clp->cl_refcount, 0);
@@ -1240,8 +1301,6 @@ static struct nfs4_client *create_client(struct xdr_netobj name, char *recdir,
1240 rpc_init_wait_queue(&clp->cl_cb_waitq, "Backchannel slot table"); 1301 rpc_init_wait_queue(&clp->cl_cb_waitq, "Backchannel slot table");
1241 copy_verf(clp, verf); 1302 copy_verf(clp, verf);
1242 rpc_copy_addr((struct sockaddr *) &clp->cl_addr, sa); 1303 rpc_copy_addr((struct sockaddr *) &clp->cl_addr, sa);
1243 clp->cl_flavor = rqstp->rq_flavor;
1244 copy_cred(&clp->cl_cred, &rqstp->rq_cred);
1245 gen_confirm(clp); 1304 gen_confirm(clp);
1246 clp->cl_cb_session = NULL; 1305 clp->cl_cb_session = NULL;
1247 return clp; 1306 return clp;
@@ -1470,18 +1529,32 @@ nfsd4_set_ex_flags(struct nfs4_client *new, struct nfsd4_exchange_id *clid)
1470 clid->flags = new->cl_exchange_flags; 1529 clid->flags = new->cl_exchange_flags;
1471} 1530}
1472 1531
1532static bool client_has_state(struct nfs4_client *clp)
1533{
1534 /*
1535 * Note clp->cl_openowners check isn't quite right: there's no
1536 * need to count owners without stateid's.
1537 *
1538 * Also note we should probably be using this in 4.0 case too.
1539 */
1540 return !list_empty(&clp->cl_openowners)
1541 || !list_empty(&clp->cl_delegations)
1542 || !list_empty(&clp->cl_sessions);
1543}
1544
1473__be32 1545__be32
1474nfsd4_exchange_id(struct svc_rqst *rqstp, 1546nfsd4_exchange_id(struct svc_rqst *rqstp,
1475 struct nfsd4_compound_state *cstate, 1547 struct nfsd4_compound_state *cstate,
1476 struct nfsd4_exchange_id *exid) 1548 struct nfsd4_exchange_id *exid)
1477{ 1549{
1478 struct nfs4_client *unconf, *conf, *new; 1550 struct nfs4_client *unconf, *conf, *new;
1479 int status; 1551 __be32 status;
1480 unsigned int strhashval; 1552 unsigned int strhashval;
1481 char dname[HEXDIR_LEN]; 1553 char dname[HEXDIR_LEN];
1482 char addr_str[INET6_ADDRSTRLEN]; 1554 char addr_str[INET6_ADDRSTRLEN];
1483 nfs4_verifier verf = exid->verifier; 1555 nfs4_verifier verf = exid->verifier;
1484 struct sockaddr *sa = svc_addr(rqstp); 1556 struct sockaddr *sa = svc_addr(rqstp);
1557 bool update = exid->flags & EXCHGID4_FLAG_UPD_CONFIRMED_REC_A;
1485 1558
1486 rpc_ntop(sa, addr_str, sizeof(addr_str)); 1559 rpc_ntop(sa, addr_str, sizeof(addr_str));
1487 dprintk("%s rqstp=%p exid=%p clname.len=%u clname.data=%p " 1560 dprintk("%s rqstp=%p exid=%p clname.len=%u clname.data=%p "
@@ -1507,71 +1580,63 @@ nfsd4_exchange_id(struct svc_rqst *rqstp,
1507 status = nfs4_make_rec_clidname(dname, &exid->clname); 1580 status = nfs4_make_rec_clidname(dname, &exid->clname);
1508 1581
1509 if (status) 1582 if (status)
1510 goto error; 1583 return status;
1511 1584
1512 strhashval = clientstr_hashval(dname); 1585 strhashval = clientstr_hashval(dname);
1513 1586
1587 /* Cases below refer to rfc 5661 section 18.35.4: */
1514 nfs4_lock_state(); 1588 nfs4_lock_state();
1515 status = nfs_ok;
1516
1517 conf = find_confirmed_client_by_str(dname, strhashval); 1589 conf = find_confirmed_client_by_str(dname, strhashval);
1518 if (conf) { 1590 if (conf) {
1519 if (!clp_used_exchangeid(conf)) { 1591 bool creds_match = same_creds(&conf->cl_cred, &rqstp->rq_cred);
1520 status = nfserr_clid_inuse; /* XXX: ? */ 1592 bool verfs_match = same_verf(&verf, &conf->cl_verifier);
1521 goto out; 1593
1522 } 1594 if (update) {
1523 if (!same_verf(&verf, &conf->cl_verifier)) { 1595 if (!clp_used_exchangeid(conf)) { /* buggy client */
1524 /* 18.35.4 case 8 */ 1596 status = nfserr_inval;
1525 if (exid->flags & EXCHGID4_FLAG_UPD_CONFIRMED_REC_A) { 1597 goto out;
1598 }
1599 if (!creds_match) { /* case 9 */
1600 status = nfserr_perm;
1601 goto out;
1602 }
1603 if (!verfs_match) { /* case 8 */
1526 status = nfserr_not_same; 1604 status = nfserr_not_same;
1527 goto out; 1605 goto out;
1528 } 1606 }
1529 /* Client reboot: destroy old state */ 1607 /* case 6 */
1530 expire_client(conf); 1608 exid->flags |= EXCHGID4_FLAG_CONFIRMED_R;
1531 goto out_new; 1609 new = conf;
1610 goto out_copy;
1532 } 1611 }
1533 if (!same_creds(&conf->cl_cred, &rqstp->rq_cred)) { 1612 if (!creds_match) { /* case 3 */
1534 /* 18.35.4 case 9 */ 1613 if (client_has_state(conf)) {
1535 if (exid->flags & EXCHGID4_FLAG_UPD_CONFIRMED_REC_A) { 1614 status = nfserr_clid_inuse;
1536 status = nfserr_perm;
1537 goto out; 1615 goto out;
1538 } 1616 }
1539 expire_client(conf); 1617 expire_client(conf);
1540 goto out_new; 1618 goto out_new;
1541 } 1619 }
1542 /* 1620 if (verfs_match) { /* case 2 */
1543 * Set bit when the owner id and verifier map to an already 1621 conf->cl_exchange_flags |= EXCHGID4_FLAG_CONFIRMED_R;
1544 * confirmed client id (18.35.3). 1622 new = conf;
1545 */ 1623 goto out_copy;
1546 exid->flags |= EXCHGID4_FLAG_CONFIRMED_R; 1624 }
1547 1625 /* case 5, client reboot */
1548 /* 1626 goto out_new;
1549 * Falling into 18.35.4 case 2, possible router replay.
1550 * Leave confirmed record intact and return same result.
1551 */
1552 copy_verf(conf, &verf);
1553 new = conf;
1554 goto out_copy;
1555 } 1627 }
1556 1628
1557 /* 18.35.4 case 7 */ 1629 if (update) { /* case 7 */
1558 if (exid->flags & EXCHGID4_FLAG_UPD_CONFIRMED_REC_A) {
1559 status = nfserr_noent; 1630 status = nfserr_noent;
1560 goto out; 1631 goto out;
1561 } 1632 }
1562 1633
1563 unconf = find_unconfirmed_client_by_str(dname, strhashval); 1634 unconf = find_unconfirmed_client_by_str(dname, strhashval);
1564 if (unconf) { 1635 if (unconf) /* case 4, possible retry or client restart */
1565 /*
1566 * Possible retry or client restart. Per 18.35.4 case 4,
1567 * a new unconfirmed record should be generated regardless
1568 * of whether any properties have changed.
1569 */
1570 expire_client(unconf); 1636 expire_client(unconf);
1571 }
1572 1637
1638 /* case 1 (normal case) */
1573out_new: 1639out_new:
1574 /* Normal case */
1575 new = create_client(exid->clname, dname, rqstp, &verf); 1640 new = create_client(exid->clname, dname, rqstp, &verf);
1576 if (new == NULL) { 1641 if (new == NULL) {
1577 status = nfserr_jukebox; 1642 status = nfserr_jukebox;
@@ -1584,7 +1649,7 @@ out_copy:
1584 exid->clientid.cl_boot = new->cl_clientid.cl_boot; 1649 exid->clientid.cl_boot = new->cl_clientid.cl_boot;
1585 exid->clientid.cl_id = new->cl_clientid.cl_id; 1650 exid->clientid.cl_id = new->cl_clientid.cl_id;
1586 1651
1587 exid->seqid = 1; 1652 exid->seqid = new->cl_cs_slot.sl_seqid + 1;
1588 nfsd4_set_ex_flags(new, exid); 1653 nfsd4_set_ex_flags(new, exid);
1589 1654
1590 dprintk("nfsd4_exchange_id seqid %d flags %x\n", 1655 dprintk("nfsd4_exchange_id seqid %d flags %x\n",
@@ -1593,12 +1658,10 @@ out_copy:
1593 1658
1594out: 1659out:
1595 nfs4_unlock_state(); 1660 nfs4_unlock_state();
1596error:
1597 dprintk("nfsd4_exchange_id returns %d\n", ntohl(status));
1598 return status; 1661 return status;
1599} 1662}
1600 1663
1601static int 1664static __be32
1602check_slot_seqid(u32 seqid, u32 slot_seqid, int slot_inuse) 1665check_slot_seqid(u32 seqid, u32 slot_seqid, int slot_inuse)
1603{ 1666{
1604 dprintk("%s enter. seqid %d slot_seqid %d\n", __func__, seqid, 1667 dprintk("%s enter. seqid %d slot_seqid %d\n", __func__, seqid,
@@ -1626,7 +1689,7 @@ check_slot_seqid(u32 seqid, u32 slot_seqid, int slot_inuse)
1626 */ 1689 */
1627static void 1690static void
1628nfsd4_cache_create_session(struct nfsd4_create_session *cr_ses, 1691nfsd4_cache_create_session(struct nfsd4_create_session *cr_ses,
1629 struct nfsd4_clid_slot *slot, int nfserr) 1692 struct nfsd4_clid_slot *slot, __be32 nfserr)
1630{ 1693{
1631 slot->sl_status = nfserr; 1694 slot->sl_status = nfserr;
1632 memcpy(&slot->sl_cr_ses, cr_ses, sizeof(*cr_ses)); 1695 memcpy(&slot->sl_cr_ses, cr_ses, sizeof(*cr_ses));
@@ -1657,7 +1720,7 @@ nfsd4_replay_create_session(struct nfsd4_create_session *cr_ses,
1657 /* seqid, slotID, slotID, slotID, status */ \ 1720 /* seqid, slotID, slotID, slotID, status */ \
1658 5 ) * sizeof(__be32)) 1721 5 ) * sizeof(__be32))
1659 1722
1660static __be32 check_forechannel_attrs(struct nfsd4_channel_attrs fchannel) 1723static bool check_forechannel_attrs(struct nfsd4_channel_attrs fchannel)
1661{ 1724{
1662 return fchannel.maxreq_sz < NFSD_MIN_REQ_HDR_SEQ_SZ 1725 return fchannel.maxreq_sz < NFSD_MIN_REQ_HDR_SEQ_SZ
1663 || fchannel.maxresp_sz < NFSD_MIN_RESP_HDR_SEQ_SZ; 1726 || fchannel.maxresp_sz < NFSD_MIN_RESP_HDR_SEQ_SZ;
@@ -1673,7 +1736,7 @@ nfsd4_create_session(struct svc_rqst *rqstp,
1673 struct nfsd4_session *new; 1736 struct nfsd4_session *new;
1674 struct nfsd4_clid_slot *cs_slot = NULL; 1737 struct nfsd4_clid_slot *cs_slot = NULL;
1675 bool confirm_me = false; 1738 bool confirm_me = false;
1676 int status = 0; 1739 __be32 status = 0;
1677 1740
1678 if (cr_ses->flags & ~SESSION4_FLAG_MASK_A) 1741 if (cr_ses->flags & ~SESSION4_FLAG_MASK_A)
1679 return nfserr_inval; 1742 return nfserr_inval;
@@ -1686,16 +1749,10 @@ nfsd4_create_session(struct svc_rqst *rqstp,
1686 cs_slot = &conf->cl_cs_slot; 1749 cs_slot = &conf->cl_cs_slot;
1687 status = check_slot_seqid(cr_ses->seqid, cs_slot->sl_seqid, 0); 1750 status = check_slot_seqid(cr_ses->seqid, cs_slot->sl_seqid, 0);
1688 if (status == nfserr_replay_cache) { 1751 if (status == nfserr_replay_cache) {
1689 dprintk("Got a create_session replay! seqid= %d\n",
1690 cs_slot->sl_seqid);
1691 /* Return the cached reply status */
1692 status = nfsd4_replay_create_session(cr_ses, cs_slot); 1752 status = nfsd4_replay_create_session(cr_ses, cs_slot);
1693 goto out; 1753 goto out;
1694 } else if (cr_ses->seqid != cs_slot->sl_seqid + 1) { 1754 } else if (cr_ses->seqid != cs_slot->sl_seqid + 1) {
1695 status = nfserr_seq_misordered; 1755 status = nfserr_seq_misordered;
1696 dprintk("Sequence misordered!\n");
1697 dprintk("Expected seqid= %d but got seqid= %d\n",
1698 cs_slot->sl_seqid, cr_ses->seqid);
1699 goto out; 1756 goto out;
1700 } 1757 }
1701 } else if (unconf) { 1758 } else if (unconf) {
@@ -1704,7 +1761,6 @@ nfsd4_create_session(struct svc_rqst *rqstp,
1704 status = nfserr_clid_inuse; 1761 status = nfserr_clid_inuse;
1705 goto out; 1762 goto out;
1706 } 1763 }
1707
1708 cs_slot = &unconf->cl_cs_slot; 1764 cs_slot = &unconf->cl_cs_slot;
1709 status = check_slot_seqid(cr_ses->seqid, cs_slot->sl_seqid, 0); 1765 status = check_slot_seqid(cr_ses->seqid, cs_slot->sl_seqid, 0);
1710 if (status) { 1766 if (status) {
@@ -1712,7 +1768,6 @@ nfsd4_create_session(struct svc_rqst *rqstp,
1712 status = nfserr_seq_misordered; 1768 status = nfserr_seq_misordered;
1713 goto out; 1769 goto out;
1714 } 1770 }
1715
1716 confirm_me = true; 1771 confirm_me = true;
1717 conf = unconf; 1772 conf = unconf;
1718 } else { 1773 } else {
@@ -1749,8 +1804,14 @@ nfsd4_create_session(struct svc_rqst *rqstp,
1749 1804
1750 /* cache solo and embedded create sessions under the state lock */ 1805 /* cache solo and embedded create sessions under the state lock */
1751 nfsd4_cache_create_session(cr_ses, cs_slot, status); 1806 nfsd4_cache_create_session(cr_ses, cs_slot, status);
1752 if (confirm_me) 1807 if (confirm_me) {
1808 unsigned int hash = clientstr_hashval(unconf->cl_recdir);
1809 struct nfs4_client *old =
1810 find_confirmed_client_by_str(conf->cl_recdir, hash);
1811 if (old)
1812 expire_client(old);
1753 move_to_confirmed(conf); 1813 move_to_confirmed(conf);
1814 }
1754out: 1815out:
1755 nfs4_unlock_state(); 1816 nfs4_unlock_state();
1756 dprintk("%s returns %d\n", __func__, ntohl(status)); 1817 dprintk("%s returns %d\n", __func__, ntohl(status));
@@ -1818,7 +1879,7 @@ nfsd4_destroy_session(struct svc_rqst *r,
1818 struct nfsd4_destroy_session *sessionid) 1879 struct nfsd4_destroy_session *sessionid)
1819{ 1880{
1820 struct nfsd4_session *ses; 1881 struct nfsd4_session *ses;
1821 u32 status = nfserr_badsession; 1882 __be32 status = nfserr_badsession;
1822 1883
1823 /* Notes: 1884 /* Notes:
1824 * - The confirmed nfs4_client->cl_sessionid holds destroyed sessinid 1885 * - The confirmed nfs4_client->cl_sessionid holds destroyed sessinid
@@ -1914,7 +1975,7 @@ nfsd4_sequence(struct svc_rqst *rqstp,
1914 struct nfsd4_session *session; 1975 struct nfsd4_session *session;
1915 struct nfsd4_slot *slot; 1976 struct nfsd4_slot *slot;
1916 struct nfsd4_conn *conn; 1977 struct nfsd4_conn *conn;
1917 int status; 1978 __be32 status;
1918 1979
1919 if (resp->opcnt != 1) 1980 if (resp->opcnt != 1)
1920 return nfserr_sequence_pos; 1981 return nfserr_sequence_pos;
@@ -2008,18 +2069,11 @@ out:
2008 return status; 2069 return status;
2009} 2070}
2010 2071
2011static inline bool has_resources(struct nfs4_client *clp)
2012{
2013 return !list_empty(&clp->cl_openowners)
2014 || !list_empty(&clp->cl_delegations)
2015 || !list_empty(&clp->cl_sessions);
2016}
2017
2018__be32 2072__be32
2019nfsd4_destroy_clientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_destroy_clientid *dc) 2073nfsd4_destroy_clientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_destroy_clientid *dc)
2020{ 2074{
2021 struct nfs4_client *conf, *unconf, *clp; 2075 struct nfs4_client *conf, *unconf, *clp;
2022 int status = 0; 2076 __be32 status = 0;
2023 2077
2024 nfs4_lock_state(); 2078 nfs4_lock_state();
2025 unconf = find_unconfirmed_client(&dc->clientid); 2079 unconf = find_unconfirmed_client(&dc->clientid);
@@ -2028,7 +2082,7 @@ nfsd4_destroy_clientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *csta
2028 if (conf) { 2082 if (conf) {
2029 clp = conf; 2083 clp = conf;
2030 2084
2031 if (!is_client_expired(conf) && has_resources(conf)) { 2085 if (!is_client_expired(conf) && client_has_state(conf)) {
2032 status = nfserr_clientid_busy; 2086 status = nfserr_clientid_busy;
2033 goto out; 2087 goto out;
2034 } 2088 }
@@ -2055,7 +2109,7 @@ out:
2055__be32 2109__be32
2056nfsd4_reclaim_complete(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_reclaim_complete *rc) 2110nfsd4_reclaim_complete(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_reclaim_complete *rc)
2057{ 2111{
2058 int status = 0; 2112 __be32 status = 0;
2059 2113
2060 if (rc->rca_one_fs) { 2114 if (rc->rca_one_fs) {
2061 if (!cstate->current_fh.fh_dentry) 2115 if (!cstate->current_fh.fh_dentry)
@@ -2106,17 +2160,13 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
2106 if (status) 2160 if (status)
2107 return status; 2161 return status;
2108 2162
2109 /*
2110 * XXX The Duplicate Request Cache (DRC) has been checked (??)
2111 * We get here on a DRC miss.
2112 */
2113
2114 strhashval = clientstr_hashval(dname); 2163 strhashval = clientstr_hashval(dname);
2115 2164
2165 /* Cases below refer to rfc 3530 section 14.2.33: */
2116 nfs4_lock_state(); 2166 nfs4_lock_state();
2117 conf = find_confirmed_client_by_str(dname, strhashval); 2167 conf = find_confirmed_client_by_str(dname, strhashval);
2118 if (conf) { 2168 if (conf) {
2119 /* RFC 3530 14.2.33 CASE 0: */ 2169 /* case 0: */
2120 status = nfserr_clid_inuse; 2170 status = nfserr_clid_inuse;
2121 if (clp_used_exchangeid(conf)) 2171 if (clp_used_exchangeid(conf))
2122 goto out; 2172 goto out;
@@ -2129,63 +2179,18 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
2129 goto out; 2179 goto out;
2130 } 2180 }
2131 } 2181 }
2132 /*
2133 * section 14.2.33 of RFC 3530 (under the heading "IMPLEMENTATION")
2134 * has a description of SETCLIENTID request processing consisting
2135 * of 5 bullet points, labeled as CASE0 - CASE4 below.
2136 */
2137 unconf = find_unconfirmed_client_by_str(dname, strhashval); 2182 unconf = find_unconfirmed_client_by_str(dname, strhashval);
2183 if (unconf)
2184 expire_client(unconf);
2138 status = nfserr_jukebox; 2185 status = nfserr_jukebox;
2139 if (!conf) { 2186 new = create_client(clname, dname, rqstp, &clverifier);
2140 /* 2187 if (new == NULL)
2141 * RFC 3530 14.2.33 CASE 4: 2188 goto out;
2142 * placed first, because it is the normal case 2189 if (conf && same_verf(&conf->cl_verifier, &clverifier))
2143 */ 2190 /* case 1: probable callback update */
2144 if (unconf)
2145 expire_client(unconf);
2146 new = create_client(clname, dname, rqstp, &clverifier);
2147 if (new == NULL)
2148 goto out;
2149 gen_clid(new);
2150 } else if (same_verf(&conf->cl_verifier, &clverifier)) {
2151 /*
2152 * RFC 3530 14.2.33 CASE 1:
2153 * probable callback update
2154 */
2155 if (unconf) {
2156 /* Note this is removing unconfirmed {*x***},
2157 * which is stronger than RFC recommended {vxc**}.
2158 * This has the advantage that there is at most
2159 * one {*x***} in either list at any time.
2160 */
2161 expire_client(unconf);
2162 }
2163 new = create_client(clname, dname, rqstp, &clverifier);
2164 if (new == NULL)
2165 goto out;
2166 copy_clid(new, conf); 2191 copy_clid(new, conf);
2167 } else if (!unconf) { 2192 else /* case 4 (new client) or cases 2, 3 (client reboot): */
2168 /*
2169 * RFC 3530 14.2.33 CASE 2:
2170 * probable client reboot; state will be removed if
2171 * confirmed.
2172 */
2173 new = create_client(clname, dname, rqstp, &clverifier);
2174 if (new == NULL)
2175 goto out;
2176 gen_clid(new);
2177 } else {
2178 /*
2179 * RFC 3530 14.2.33 CASE 3:
2180 * probable client reboot; state will be removed if
2181 * confirmed.
2182 */
2183 expire_client(unconf);
2184 new = create_client(clname, dname, rqstp, &clverifier);
2185 if (new == NULL)
2186 goto out;
2187 gen_clid(new); 2193 gen_clid(new);
2188 }
2189 /* 2194 /*
2190 * XXX: we should probably set this at creation time, and check 2195 * XXX: we should probably set this at creation time, and check
2191 * for consistent minorversion use throughout: 2196 * for consistent minorversion use throughout:
@@ -2203,17 +2208,11 @@ out:
2203} 2208}
2204 2209
2205 2210
2206/*
2207 * Section 14.2.34 of RFC 3530 (under the heading "IMPLEMENTATION") has
2208 * a description of SETCLIENTID_CONFIRM request processing consisting of 4
2209 * bullets, labeled as CASE1 - CASE4 below.
2210 */
2211__be32 2211__be32
2212nfsd4_setclientid_confirm(struct svc_rqst *rqstp, 2212nfsd4_setclientid_confirm(struct svc_rqst *rqstp,
2213 struct nfsd4_compound_state *cstate, 2213 struct nfsd4_compound_state *cstate,
2214 struct nfsd4_setclientid_confirm *setclientid_confirm) 2214 struct nfsd4_setclientid_confirm *setclientid_confirm)
2215{ 2215{
2216 struct sockaddr *sa = svc_addr(rqstp);
2217 struct nfs4_client *conf, *unconf; 2216 struct nfs4_client *conf, *unconf;
2218 nfs4_verifier confirm = setclientid_confirm->sc_confirm; 2217 nfs4_verifier confirm = setclientid_confirm->sc_confirm;
2219 clientid_t * clid = &setclientid_confirm->sc_clientid; 2218 clientid_t * clid = &setclientid_confirm->sc_clientid;
@@ -2221,84 +2220,44 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp,
2221 2220
2222 if (STALE_CLIENTID(clid)) 2221 if (STALE_CLIENTID(clid))
2223 return nfserr_stale_clientid; 2222 return nfserr_stale_clientid;
2224 /*
2225 * XXX The Duplicate Request Cache (DRC) has been checked (??)
2226 * We get here on a DRC miss.
2227 */
2228
2229 nfs4_lock_state(); 2223 nfs4_lock_state();
2230 2224
2231 conf = find_confirmed_client(clid); 2225 conf = find_confirmed_client(clid);
2232 unconf = find_unconfirmed_client(clid); 2226 unconf = find_unconfirmed_client(clid);
2233
2234 status = nfserr_clid_inuse;
2235 if (conf && !rpc_cmp_addr((struct sockaddr *) &conf->cl_addr, sa))
2236 goto out;
2237 if (unconf && !rpc_cmp_addr((struct sockaddr *) &unconf->cl_addr, sa))
2238 goto out;
2239
2240 /* 2227 /*
2241 * section 14.2.34 of RFC 3530 has a description of 2228 * We try hard to give out unique clientid's, so if we get an
2242 * SETCLIENTID_CONFIRM request processing consisting 2229 * attempt to confirm the same clientid with a different cred,
2243 * of 4 bullet points, labeled as CASE1 - CASE4 below. 2230 * there's a bug somewhere. Let's charitably assume it's our
2231 * bug.
2244 */ 2232 */
2245 if (conf && unconf && same_verf(&confirm, &unconf->cl_confirm)) { 2233 status = nfserr_serverfault;
2246 /* 2234 if (unconf && !same_creds(&unconf->cl_cred, &rqstp->rq_cred))
2247 * RFC 3530 14.2.34 CASE 1: 2235 goto out;
2248 * callback update 2236 if (conf && !same_creds(&conf->cl_cred, &rqstp->rq_cred))
2249 */ 2237 goto out;
2250 if (!same_creds(&conf->cl_cred, &unconf->cl_cred)) 2238 /* cases below refer to rfc 3530 section 14.2.34: */
2251 status = nfserr_clid_inuse; 2239 if (!unconf || !same_verf(&confirm, &unconf->cl_confirm)) {
2252 else { 2240 if (conf && !unconf) /* case 2: probable retransmit */
2253 nfsd4_change_callback(conf, &unconf->cl_cb_conn);
2254 nfsd4_probe_callback(conf);
2255 expire_client(unconf);
2256 status = nfs_ok; 2241 status = nfs_ok;
2242 else /* case 4: client hasn't noticed we rebooted yet? */
2243 status = nfserr_stale_clientid;
2244 goto out;
2245 }
2246 status = nfs_ok;
2247 if (conf) { /* case 1: callback update */
2248 nfsd4_change_callback(conf, &unconf->cl_cb_conn);
2249 nfsd4_probe_callback(conf);
2250 expire_client(unconf);
2251 } else { /* case 3: normal case; new or rebooted client */
2252 unsigned int hash = clientstr_hashval(unconf->cl_recdir);
2257 2253
2254 conf = find_confirmed_client_by_str(unconf->cl_recdir, hash);
2255 if (conf) {
2256 nfsd4_client_record_remove(conf);
2257 expire_client(conf);
2258 } 2258 }
2259 } else if (conf && !unconf) { 2259 move_to_confirmed(unconf);
2260 /* 2260 nfsd4_probe_callback(unconf);
2261 * RFC 3530 14.2.34 CASE 2:
2262 * probable retransmitted request; play it safe and
2263 * do nothing.
2264 */
2265 if (!same_creds(&conf->cl_cred, &rqstp->rq_cred))
2266 status = nfserr_clid_inuse;
2267 else
2268 status = nfs_ok;
2269 } else if (!conf && unconf
2270 && same_verf(&unconf->cl_confirm, &confirm)) {
2271 /*
2272 * RFC 3530 14.2.34 CASE 3:
2273 * Normal case; new or rebooted client:
2274 */
2275 if (!same_creds(&unconf->cl_cred, &rqstp->rq_cred)) {
2276 status = nfserr_clid_inuse;
2277 } else {
2278 unsigned int hash =
2279 clientstr_hashval(unconf->cl_recdir);
2280 conf = find_confirmed_client_by_str(unconf->cl_recdir,
2281 hash);
2282 if (conf) {
2283 nfsd4_client_record_remove(conf);
2284 expire_client(conf);
2285 }
2286 move_to_confirmed(unconf);
2287 conf = unconf;
2288 nfsd4_probe_callback(conf);
2289 status = nfs_ok;
2290 }
2291 } else if ((!conf || (conf && !same_verf(&conf->cl_confirm, &confirm)))
2292 && (!unconf || (unconf && !same_verf(&unconf->cl_confirm,
2293 &confirm)))) {
2294 /*
2295 * RFC 3530 14.2.34 CASE 4:
2296 * Client probably hasn't noticed that we rebooted yet.
2297 */
2298 status = nfserr_stale_clientid;
2299 } else {
2300 /* check that we have hit one of the cases...*/
2301 status = nfserr_clid_inuse;
2302 } 2261 }
2303out: 2262out:
2304 nfs4_unlock_state(); 2263 nfs4_unlock_state();
@@ -2454,8 +2413,8 @@ static void init_open_stateid(struct nfs4_ol_stateid *stp, struct nfs4_file *fp,
2454 stp->st_file = fp; 2413 stp->st_file = fp;
2455 stp->st_access_bmap = 0; 2414 stp->st_access_bmap = 0;
2456 stp->st_deny_bmap = 0; 2415 stp->st_deny_bmap = 0;
2457 __set_bit(open->op_share_access, &stp->st_access_bmap); 2416 set_access(open->op_share_access, stp);
2458 __set_bit(open->op_share_deny, &stp->st_deny_bmap); 2417 set_deny(open->op_share_deny, stp);
2459 stp->st_openstp = NULL; 2418 stp->st_openstp = NULL;
2460} 2419}
2461 2420
@@ -2534,8 +2493,8 @@ nfs4_share_conflict(struct svc_fh *current_fh, unsigned int deny_type)
2534 ret = nfserr_locked; 2493 ret = nfserr_locked;
2535 /* Search for conflicting share reservations */ 2494 /* Search for conflicting share reservations */
2536 list_for_each_entry(stp, &fp->fi_stateids, st_perfile) { 2495 list_for_each_entry(stp, &fp->fi_stateids, st_perfile) {
2537 if (test_bit(deny_type, &stp->st_deny_bmap) || 2496 if (test_deny(deny_type, stp) ||
2538 test_bit(NFS4_SHARE_DENY_BOTH, &stp->st_deny_bmap)) 2497 test_deny(NFS4_SHARE_DENY_BOTH, stp))
2539 goto out; 2498 goto out;
2540 } 2499 }
2541 ret = nfs_ok; 2500 ret = nfs_ok;
@@ -2791,7 +2750,7 @@ nfs4_upgrade_open(struct svc_rqst *rqstp, struct nfs4_file *fp, struct svc_fh *c
2791 bool new_access; 2750 bool new_access;
2792 __be32 status; 2751 __be32 status;
2793 2752
2794 new_access = !test_bit(op_share_access, &stp->st_access_bmap); 2753 new_access = !test_access(op_share_access, stp);
2795 if (new_access) { 2754 if (new_access) {
2796 status = nfs4_get_vfs_file(rqstp, fp, cur_fh, open); 2755 status = nfs4_get_vfs_file(rqstp, fp, cur_fh, open);
2797 if (status) 2756 if (status)
@@ -2806,8 +2765,8 @@ nfs4_upgrade_open(struct svc_rqst *rqstp, struct nfs4_file *fp, struct svc_fh *c
2806 return status; 2765 return status;
2807 } 2766 }
2808 /* remember the open */ 2767 /* remember the open */
2809 __set_bit(op_share_access, &stp->st_access_bmap); 2768 set_access(op_share_access, stp);
2810 __set_bit(open->op_share_deny, &stp->st_deny_bmap); 2769 set_deny(open->op_share_deny, stp);
2811 2770
2812 return nfs_ok; 2771 return nfs_ok;
2813} 2772}
@@ -3155,10 +3114,17 @@ out:
3155static struct lock_manager nfsd4_manager = { 3114static struct lock_manager nfsd4_manager = {
3156}; 3115};
3157 3116
3117static bool grace_ended;
3118
3158static void 3119static void
3159nfsd4_end_grace(void) 3120nfsd4_end_grace(void)
3160{ 3121{
3122 /* do nothing if grace period already ended */
3123 if (grace_ended)
3124 return;
3125
3161 dprintk("NFSD: end of grace period\n"); 3126 dprintk("NFSD: end of grace period\n");
3127 grace_ended = true;
3162 nfsd4_record_grace_done(&init_net, boot_time); 3128 nfsd4_record_grace_done(&init_net, boot_time);
3163 locks_end_grace(&nfsd4_manager); 3129 locks_end_grace(&nfsd4_manager);
3164 /* 3130 /*
@@ -3183,8 +3149,7 @@ nfs4_laundromat(void)
3183 nfs4_lock_state(); 3149 nfs4_lock_state();
3184 3150
3185 dprintk("NFSD: laundromat service - starting\n"); 3151 dprintk("NFSD: laundromat service - starting\n");
3186 if (locks_in_grace()) 3152 nfsd4_end_grace();
3187 nfsd4_end_grace();
3188 INIT_LIST_HEAD(&reaplist); 3153 INIT_LIST_HEAD(&reaplist);
3189 spin_lock(&client_lock); 3154 spin_lock(&client_lock);
3190 list_for_each_safe(pos, next, &client_lru) { 3155 list_for_each_safe(pos, next, &client_lru) {
@@ -3276,18 +3241,18 @@ STALE_STATEID(stateid_t *stateid)
3276} 3241}
3277 3242
3278static inline int 3243static inline int
3279access_permit_read(unsigned long access_bmap) 3244access_permit_read(struct nfs4_ol_stateid *stp)
3280{ 3245{
3281 return test_bit(NFS4_SHARE_ACCESS_READ, &access_bmap) || 3246 return test_access(NFS4_SHARE_ACCESS_READ, stp) ||
3282 test_bit(NFS4_SHARE_ACCESS_BOTH, &access_bmap) || 3247 test_access(NFS4_SHARE_ACCESS_BOTH, stp) ||
3283 test_bit(NFS4_SHARE_ACCESS_WRITE, &access_bmap); 3248 test_access(NFS4_SHARE_ACCESS_WRITE, stp);
3284} 3249}
3285 3250
3286static inline int 3251static inline int
3287access_permit_write(unsigned long access_bmap) 3252access_permit_write(struct nfs4_ol_stateid *stp)
3288{ 3253{
3289 return test_bit(NFS4_SHARE_ACCESS_WRITE, &access_bmap) || 3254 return test_access(NFS4_SHARE_ACCESS_WRITE, stp) ||
3290 test_bit(NFS4_SHARE_ACCESS_BOTH, &access_bmap); 3255 test_access(NFS4_SHARE_ACCESS_BOTH, stp);
3291} 3256}
3292 3257
3293static 3258static
@@ -3298,9 +3263,9 @@ __be32 nfs4_check_openmode(struct nfs4_ol_stateid *stp, int flags)
3298 /* For lock stateid's, we test the parent open, not the lock: */ 3263 /* For lock stateid's, we test the parent open, not the lock: */
3299 if (stp->st_openstp) 3264 if (stp->st_openstp)
3300 stp = stp->st_openstp; 3265 stp = stp->st_openstp;
3301 if ((flags & WR_STATE) && (!access_permit_write(stp->st_access_bmap))) 3266 if ((flags & WR_STATE) && !access_permit_write(stp))
3302 goto out; 3267 goto out;
3303 if ((flags & RD_STATE) && (!access_permit_read(stp->st_access_bmap))) 3268 if ((flags & RD_STATE) && !access_permit_read(stp))
3304 goto out; 3269 goto out;
3305 status = nfs_ok; 3270 status = nfs_ok;
3306out: 3271out:
@@ -3340,7 +3305,7 @@ static bool stateid_generation_after(stateid_t *a, stateid_t *b)
3340 return (s32)a->si_generation - (s32)b->si_generation > 0; 3305 return (s32)a->si_generation - (s32)b->si_generation > 0;
3341} 3306}
3342 3307
3343static int check_stateid_generation(stateid_t *in, stateid_t *ref, bool has_session) 3308static __be32 check_stateid_generation(stateid_t *in, stateid_t *ref, bool has_session)
3344{ 3309{
3345 /* 3310 /*
3346 * When sessions are used the stateid generation number is ignored 3311 * When sessions are used the stateid generation number is ignored
@@ -3649,10 +3614,10 @@ out:
3649 3614
3650static inline void nfs4_stateid_downgrade_bit(struct nfs4_ol_stateid *stp, u32 access) 3615static inline void nfs4_stateid_downgrade_bit(struct nfs4_ol_stateid *stp, u32 access)
3651{ 3616{
3652 if (!test_bit(access, &stp->st_access_bmap)) 3617 if (!test_access(access, stp))
3653 return; 3618 return;
3654 nfs4_file_put_access(stp->st_file, nfs4_access_to_omode(access)); 3619 nfs4_file_put_access(stp->st_file, nfs4_access_to_omode(access));
3655 __clear_bit(access, &stp->st_access_bmap); 3620 clear_access(access, stp);
3656} 3621}
3657 3622
3658static inline void nfs4_stateid_downgrade(struct nfs4_ol_stateid *stp, u32 to_access) 3623static inline void nfs4_stateid_downgrade(struct nfs4_ol_stateid *stp, u32 to_access)
@@ -3674,12 +3639,12 @@ static inline void nfs4_stateid_downgrade(struct nfs4_ol_stateid *stp, u32 to_ac
3674} 3639}
3675 3640
3676static void 3641static void
3677reset_union_bmap_deny(unsigned long deny, unsigned long *bmap) 3642reset_union_bmap_deny(unsigned long deny, struct nfs4_ol_stateid *stp)
3678{ 3643{
3679 int i; 3644 int i;
3680 for (i = 0; i < 4; i++) { 3645 for (i = 0; i < 4; i++) {
3681 if ((i & deny) != i) 3646 if ((i & deny) != i)
3682 __clear_bit(i, bmap); 3647 clear_deny(i, stp);
3683 } 3648 }
3684} 3649}
3685 3650
@@ -3706,19 +3671,19 @@ nfsd4_open_downgrade(struct svc_rqst *rqstp,
3706 if (status) 3671 if (status)
3707 goto out; 3672 goto out;
3708 status = nfserr_inval; 3673 status = nfserr_inval;
3709 if (!test_bit(od->od_share_access, &stp->st_access_bmap)) { 3674 if (!test_access(od->od_share_access, stp)) {
3710 dprintk("NFSD:access not a subset current bitmap: 0x%lx, input access=%08x\n", 3675 dprintk("NFSD: access not a subset current bitmap: 0x%lx, input access=%08x\n",
3711 stp->st_access_bmap, od->od_share_access); 3676 stp->st_access_bmap, od->od_share_access);
3712 goto out; 3677 goto out;
3713 } 3678 }
3714 if (!test_bit(od->od_share_deny, &stp->st_deny_bmap)) { 3679 if (!test_deny(od->od_share_deny, stp)) {
3715 dprintk("NFSD:deny not a subset current bitmap: 0x%lx, input deny=%08x\n", 3680 dprintk("NFSD:deny not a subset current bitmap: 0x%lx, input deny=%08x\n",
3716 stp->st_deny_bmap, od->od_share_deny); 3681 stp->st_deny_bmap, od->od_share_deny);
3717 goto out; 3682 goto out;
3718 } 3683 }
3719 nfs4_stateid_downgrade(stp, od->od_share_access); 3684 nfs4_stateid_downgrade(stp, od->od_share_access);
3720 3685
3721 reset_union_bmap_deny(od->od_share_deny, &stp->st_deny_bmap); 3686 reset_union_bmap_deny(od->od_share_deny, stp);
3722 3687
3723 update_stateid(&stp->st_stid.sc_stateid); 3688 update_stateid(&stp->st_stid.sc_stateid);
3724 memcpy(&od->od_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t)); 3689 memcpy(&od->od_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
@@ -4008,13 +3973,13 @@ static void get_lock_access(struct nfs4_ol_stateid *lock_stp, u32 access)
4008 struct nfs4_file *fp = lock_stp->st_file; 3973 struct nfs4_file *fp = lock_stp->st_file;
4009 int oflag = nfs4_access_to_omode(access); 3974 int oflag = nfs4_access_to_omode(access);
4010 3975
4011 if (test_bit(access, &lock_stp->st_access_bmap)) 3976 if (test_access(access, lock_stp))
4012 return; 3977 return;
4013 nfs4_file_get_access(fp, oflag); 3978 nfs4_file_get_access(fp, oflag);
4014 __set_bit(access, &lock_stp->st_access_bmap); 3979 set_access(access, lock_stp);
4015} 3980}
4016 3981
4017__be32 lookup_or_create_lock_state(struct nfsd4_compound_state *cstate, struct nfs4_ol_stateid *ost, struct nfsd4_lock *lock, struct nfs4_ol_stateid **lst, bool *new) 3982static __be32 lookup_or_create_lock_state(struct nfsd4_compound_state *cstate, struct nfs4_ol_stateid *ost, struct nfsd4_lock *lock, struct nfs4_ol_stateid **lst, bool *new)
4018{ 3983{
4019 struct nfs4_file *fi = ost->st_file; 3984 struct nfs4_file *fi = ost->st_file;
4020 struct nfs4_openowner *oo = openowner(ost->st_stateowner); 3985 struct nfs4_openowner *oo = openowner(ost->st_stateowner);
@@ -4055,7 +4020,6 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
4055 struct nfs4_openowner *open_sop = NULL; 4020 struct nfs4_openowner *open_sop = NULL;
4056 struct nfs4_lockowner *lock_sop = NULL; 4021 struct nfs4_lockowner *lock_sop = NULL;
4057 struct nfs4_ol_stateid *lock_stp; 4022 struct nfs4_ol_stateid *lock_stp;
4058 struct nfs4_file *fp;
4059 struct file *filp = NULL; 4023 struct file *filp = NULL;
4060 struct file_lock file_lock; 4024 struct file_lock file_lock;
4061 struct file_lock conflock; 4025 struct file_lock conflock;
@@ -4123,7 +4087,6 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
4123 goto out; 4087 goto out;
4124 } 4088 }
4125 lock_sop = lockowner(lock_stp->st_stateowner); 4089 lock_sop = lockowner(lock_stp->st_stateowner);
4126 fp = lock_stp->st_file;
4127 4090
4128 lkflg = setlkflg(lock->lk_type); 4091 lkflg = setlkflg(lock->lk_type);
4129 status = nfs4_check_openmode(lock_stp, lkflg); 4092 status = nfs4_check_openmode(lock_stp, lkflg);
@@ -4715,6 +4678,7 @@ nfs4_state_start(void)
4715 nfsd4_client_tracking_init(&init_net); 4678 nfsd4_client_tracking_init(&init_net);
4716 boot_time = get_seconds(); 4679 boot_time = get_seconds();
4717 locks_start_grace(&nfsd4_manager); 4680 locks_start_grace(&nfsd4_manager);
4681 grace_ended = false;
4718 printk(KERN_INFO "NFSD: starting %ld-second grace period\n", 4682 printk(KERN_INFO "NFSD: starting %ld-second grace period\n",
4719 nfsd4_grace); 4683 nfsd4_grace);
4720 ret = set_callback_cred(); 4684 ret = set_callback_cred();
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 74c00bc92b9a..4949667c84ea 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -1674,12 +1674,12 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
1674 1674
1675static void write32(__be32 **p, u32 n) 1675static void write32(__be32 **p, u32 n)
1676{ 1676{
1677 *(*p)++ = n; 1677 *(*p)++ = htonl(n);
1678} 1678}
1679 1679
1680static void write64(__be32 **p, u64 n) 1680static void write64(__be32 **p, u64 n)
1681{ 1681{
1682 write32(p, (u32)(n >> 32)); 1682 write32(p, (n >> 32));
1683 write32(p, (u32)n); 1683 write32(p, (u32)n);
1684} 1684}
1685 1685
@@ -1744,15 +1744,16 @@ static void encode_seqid_op_tail(struct nfsd4_compoundres *resp, __be32 *save, _
1744} 1744}
1745 1745
1746/* Encode as an array of strings the string given with components 1746/* Encode as an array of strings the string given with components
1747 * separated @sep. 1747 * separated @sep, escaped with esc_enter and esc_exit.
1748 */ 1748 */
1749static __be32 nfsd4_encode_components(char sep, char *components, 1749static __be32 nfsd4_encode_components_esc(char sep, char *components,
1750 __be32 **pp, int *buflen) 1750 __be32 **pp, int *buflen,
1751 char esc_enter, char esc_exit)
1751{ 1752{
1752 __be32 *p = *pp; 1753 __be32 *p = *pp;
1753 __be32 *countp = p; 1754 __be32 *countp = p;
1754 int strlen, count=0; 1755 int strlen, count=0;
1755 char *str, *end; 1756 char *str, *end, *next;
1756 1757
1757 dprintk("nfsd4_encode_components(%s)\n", components); 1758 dprintk("nfsd4_encode_components(%s)\n", components);
1758 if ((*buflen -= 4) < 0) 1759 if ((*buflen -= 4) < 0)
@@ -1760,8 +1761,23 @@ static __be32 nfsd4_encode_components(char sep, char *components,
1760 WRITE32(0); /* We will fill this in with @count later */ 1761 WRITE32(0); /* We will fill this in with @count later */
1761 end = str = components; 1762 end = str = components;
1762 while (*end) { 1763 while (*end) {
1763 for (; *end && (*end != sep); end++) 1764 bool found_esc = false;
1764 ; /* Point to end of component */ 1765
1766 /* try to parse as esc_start, ..., esc_end, sep */
1767 if (*str == esc_enter) {
1768 for (; *end && (*end != esc_exit); end++)
1769 /* find esc_exit or end of string */;
1770 next = end + 1;
1771 if (*end && (!*next || *next == sep)) {
1772 str++;
1773 found_esc = true;
1774 }
1775 }
1776
1777 if (!found_esc)
1778 for (; *end && (*end != sep); end++)
1779 /* find sep or end of string */;
1780
1765 strlen = end - str; 1781 strlen = end - str;
1766 if (strlen) { 1782 if (strlen) {
1767 if ((*buflen -= ((XDR_QUADLEN(strlen) << 2) + 4)) < 0) 1783 if ((*buflen -= ((XDR_QUADLEN(strlen) << 2) + 4)) < 0)
@@ -1780,6 +1796,15 @@ static __be32 nfsd4_encode_components(char sep, char *components,
1780 return 0; 1796 return 0;
1781} 1797}
1782 1798
1799/* Encode as an array of strings the string given with components
1800 * separated @sep.
1801 */
1802static __be32 nfsd4_encode_components(char sep, char *components,
1803 __be32 **pp, int *buflen)
1804{
1805 return nfsd4_encode_components_esc(sep, components, pp, buflen, 0, 0);
1806}
1807
1783/* 1808/*
1784 * encode a location element of a fs_locations structure 1809 * encode a location element of a fs_locations structure
1785 */ 1810 */
@@ -1789,7 +1814,8 @@ static __be32 nfsd4_encode_fs_location4(struct nfsd4_fs_location *location,
1789 __be32 status; 1814 __be32 status;
1790 __be32 *p = *pp; 1815 __be32 *p = *pp;
1791 1816
1792 status = nfsd4_encode_components(':', location->hosts, &p, buflen); 1817 status = nfsd4_encode_components_esc(':', location->hosts, &p, buflen,
1818 '[', ']');
1793 if (status) 1819 if (status)
1794 return status; 1820 return status;
1795 status = nfsd4_encode_components('/', location->path, &p, buflen); 1821 status = nfsd4_encode_components('/', location->path, &p, buflen);
@@ -3251,7 +3277,7 @@ nfsd4_encode_write(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_w
3251} 3277}
3252 3278
3253static __be32 3279static __be32
3254nfsd4_encode_exchange_id(struct nfsd4_compoundres *resp, int nfserr, 3280nfsd4_encode_exchange_id(struct nfsd4_compoundres *resp, __be32 nfserr,
3255 struct nfsd4_exchange_id *exid) 3281 struct nfsd4_exchange_id *exid)
3256{ 3282{
3257 __be32 *p; 3283 __be32 *p;
@@ -3306,7 +3332,7 @@ nfsd4_encode_exchange_id(struct nfsd4_compoundres *resp, int nfserr,
3306} 3332}
3307 3333
3308static __be32 3334static __be32
3309nfsd4_encode_create_session(struct nfsd4_compoundres *resp, int nfserr, 3335nfsd4_encode_create_session(struct nfsd4_compoundres *resp, __be32 nfserr,
3310 struct nfsd4_create_session *sess) 3336 struct nfsd4_create_session *sess)
3311{ 3337{
3312 __be32 *p; 3338 __be32 *p;
@@ -3355,14 +3381,14 @@ nfsd4_encode_create_session(struct nfsd4_compoundres *resp, int nfserr,
3355} 3381}
3356 3382
3357static __be32 3383static __be32
3358nfsd4_encode_destroy_session(struct nfsd4_compoundres *resp, int nfserr, 3384nfsd4_encode_destroy_session(struct nfsd4_compoundres *resp, __be32 nfserr,
3359 struct nfsd4_destroy_session *destroy_session) 3385 struct nfsd4_destroy_session *destroy_session)
3360{ 3386{
3361 return nfserr; 3387 return nfserr;
3362} 3388}
3363 3389
3364static __be32 3390static __be32
3365nfsd4_encode_free_stateid(struct nfsd4_compoundres *resp, int nfserr, 3391nfsd4_encode_free_stateid(struct nfsd4_compoundres *resp, __be32 nfserr,
3366 struct nfsd4_free_stateid *free_stateid) 3392 struct nfsd4_free_stateid *free_stateid)
3367{ 3393{
3368 __be32 *p; 3394 __be32 *p;
@@ -3371,13 +3397,13 @@ nfsd4_encode_free_stateid(struct nfsd4_compoundres *resp, int nfserr,
3371 return nfserr; 3397 return nfserr;
3372 3398
3373 RESERVE_SPACE(4); 3399 RESERVE_SPACE(4);
3374 WRITE32(nfserr); 3400 *p++ = nfserr;
3375 ADJUST_ARGS(); 3401 ADJUST_ARGS();
3376 return nfserr; 3402 return nfserr;
3377} 3403}
3378 3404
3379static __be32 3405static __be32
3380nfsd4_encode_sequence(struct nfsd4_compoundres *resp, int nfserr, 3406nfsd4_encode_sequence(struct nfsd4_compoundres *resp, __be32 nfserr,
3381 struct nfsd4_sequence *seq) 3407 struct nfsd4_sequence *seq)
3382{ 3408{
3383 __be32 *p; 3409 __be32 *p;
@@ -3399,8 +3425,8 @@ nfsd4_encode_sequence(struct nfsd4_compoundres *resp, int nfserr,
3399 return 0; 3425 return 0;
3400} 3426}
3401 3427
3402__be32 3428static __be32
3403nfsd4_encode_test_stateid(struct nfsd4_compoundres *resp, int nfserr, 3429nfsd4_encode_test_stateid(struct nfsd4_compoundres *resp, __be32 nfserr,
3404 struct nfsd4_test_stateid *test_stateid) 3430 struct nfsd4_test_stateid *test_stateid)
3405{ 3431{
3406 struct nfsd4_test_stateid_id *stateid, *next; 3432 struct nfsd4_test_stateid_id *stateid, *next;
@@ -3503,7 +3529,7 @@ static nfsd4_enc nfsd4_enc_ops[] = {
3503 * Our se_fmaxresp_cached will always be a multiple of PAGE_SIZE, and so 3529 * Our se_fmaxresp_cached will always be a multiple of PAGE_SIZE, and so
3504 * will be at least a page and will therefore hold the xdr_buf head. 3530 * will be at least a page and will therefore hold the xdr_buf head.
3505 */ 3531 */
3506int nfsd4_check_resp_size(struct nfsd4_compoundres *resp, u32 pad) 3532__be32 nfsd4_check_resp_size(struct nfsd4_compoundres *resp, u32 pad)
3507{ 3533{
3508 struct xdr_buf *xb = &resp->rqstp->rq_res; 3534 struct xdr_buf *xb = &resp->rqstp->rq_res;
3509 struct nfsd4_session *session = NULL; 3535 struct nfsd4_session *session = NULL;
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index 2c53be6d3579..c55298ed5772 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -127,7 +127,17 @@ static const struct file_operations transaction_ops = {
127 127
128static int exports_open(struct inode *inode, struct file *file) 128static int exports_open(struct inode *inode, struct file *file)
129{ 129{
130 return seq_open(file, &nfs_exports_op); 130 int err;
131 struct seq_file *seq;
132 struct nfsd_net *nn = net_generic(&init_net, nfsd_net_id);
133
134 err = seq_open(file, &nfs_exports_op);
135 if (err)
136 return err;
137
138 seq = file->private_data;
139 seq->private = nn->svc_export_cache;
140 return 0;
131} 141}
132 142
133static const struct file_operations exports_operations = { 143static const struct file_operations exports_operations = {
@@ -345,7 +355,7 @@ static ssize_t write_filehandle(struct file *file, char *buf, size_t size)
345 if (!dom) 355 if (!dom)
346 return -ENOMEM; 356 return -ENOMEM;
347 357
348 len = exp_rootfh(dom, path, &fh, maxsize); 358 len = exp_rootfh(&init_net, dom, path, &fh, maxsize);
349 auth_domain_put(dom); 359 auth_domain_put(dom);
350 if (len) 360 if (len)
351 return len; 361 return len;
@@ -651,6 +661,7 @@ static ssize_t __write_ports_addfd(char *buf)
651{ 661{
652 char *mesg = buf; 662 char *mesg = buf;
653 int fd, err; 663 int fd, err;
664 struct net *net = &init_net;
654 665
655 err = get_int(&mesg, &fd); 666 err = get_int(&mesg, &fd);
656 if (err != 0 || fd < 0) 667 if (err != 0 || fd < 0)
@@ -662,6 +673,8 @@ static ssize_t __write_ports_addfd(char *buf)
662 673
663 err = svc_addsock(nfsd_serv, fd, buf, SIMPLE_TRANSACTION_LIMIT); 674 err = svc_addsock(nfsd_serv, fd, buf, SIMPLE_TRANSACTION_LIMIT);
664 if (err < 0) { 675 if (err < 0) {
676 if (nfsd_serv->sv_nrthreads == 1)
677 svc_shutdown_net(nfsd_serv, net);
665 svc_destroy(nfsd_serv); 678 svc_destroy(nfsd_serv);
666 return err; 679 return err;
667 } 680 }
@@ -699,6 +712,7 @@ static ssize_t __write_ports_addxprt(char *buf)
699 char transport[16]; 712 char transport[16];
700 struct svc_xprt *xprt; 713 struct svc_xprt *xprt;
701 int port, err; 714 int port, err;
715 struct net *net = &init_net;
702 716
703 if (sscanf(buf, "%15s %4u", transport, &port) != 2) 717 if (sscanf(buf, "%15s %4u", transport, &port) != 2)
704 return -EINVAL; 718 return -EINVAL;
@@ -710,12 +724,12 @@ static ssize_t __write_ports_addxprt(char *buf)
710 if (err != 0) 724 if (err != 0)
711 return err; 725 return err;
712 726
713 err = svc_create_xprt(nfsd_serv, transport, &init_net, 727 err = svc_create_xprt(nfsd_serv, transport, net,
714 PF_INET, port, SVC_SOCK_ANONYMOUS); 728 PF_INET, port, SVC_SOCK_ANONYMOUS);
715 if (err < 0) 729 if (err < 0)
716 goto out_err; 730 goto out_err;
717 731
718 err = svc_create_xprt(nfsd_serv, transport, &init_net, 732 err = svc_create_xprt(nfsd_serv, transport, net,
719 PF_INET6, port, SVC_SOCK_ANONYMOUS); 733 PF_INET6, port, SVC_SOCK_ANONYMOUS);
720 if (err < 0 && err != -EAFNOSUPPORT) 734 if (err < 0 && err != -EAFNOSUPPORT)
721 goto out_close; 735 goto out_close;
@@ -724,12 +738,14 @@ static ssize_t __write_ports_addxprt(char *buf)
724 nfsd_serv->sv_nrthreads--; 738 nfsd_serv->sv_nrthreads--;
725 return 0; 739 return 0;
726out_close: 740out_close:
727 xprt = svc_find_xprt(nfsd_serv, transport, &init_net, PF_INET, port); 741 xprt = svc_find_xprt(nfsd_serv, transport, net, PF_INET, port);
728 if (xprt != NULL) { 742 if (xprt != NULL) {
729 svc_close_xprt(xprt); 743 svc_close_xprt(xprt);
730 svc_xprt_put(xprt); 744 svc_xprt_put(xprt);
731 } 745 }
732out_err: 746out_err:
747 if (nfsd_serv->sv_nrthreads == 1)
748 svc_shutdown_net(nfsd_serv, net);
733 svc_destroy(nfsd_serv); 749 svc_destroy(nfsd_serv);
734 return err; 750 return err;
735} 751}
@@ -1127,7 +1143,34 @@ static int create_proc_exports_entry(void)
1127#endif 1143#endif
1128 1144
1129int nfsd_net_id; 1145int nfsd_net_id;
1146
1147static __net_init int nfsd_init_net(struct net *net)
1148{
1149 int retval;
1150
1151 retval = nfsd_export_init(net);
1152 if (retval)
1153 goto out_export_error;
1154 retval = nfsd_idmap_init(net);
1155 if (retval)
1156 goto out_idmap_error;
1157 return 0;
1158
1159out_idmap_error:
1160 nfsd_export_shutdown(net);
1161out_export_error:
1162 return retval;
1163}
1164
1165static __net_exit void nfsd_exit_net(struct net *net)
1166{
1167 nfsd_idmap_shutdown(net);
1168 nfsd_export_shutdown(net);
1169}
1170
1130static struct pernet_operations nfsd_net_ops = { 1171static struct pernet_operations nfsd_net_ops = {
1172 .init = nfsd_init_net,
1173 .exit = nfsd_exit_net,
1131 .id = &nfsd_net_id, 1174 .id = &nfsd_net_id,
1132 .size = sizeof(struct nfsd_net), 1175 .size = sizeof(struct nfsd_net),
1133}; 1176};
@@ -1154,16 +1197,10 @@ static int __init init_nfsd(void)
1154 retval = nfsd_reply_cache_init(); 1197 retval = nfsd_reply_cache_init();
1155 if (retval) 1198 if (retval)
1156 goto out_free_stat; 1199 goto out_free_stat;
1157 retval = nfsd_export_init();
1158 if (retval)
1159 goto out_free_cache;
1160 nfsd_lockd_init(); /* lockd->nfsd callbacks */ 1200 nfsd_lockd_init(); /* lockd->nfsd callbacks */
1161 retval = nfsd_idmap_init();
1162 if (retval)
1163 goto out_free_lockd;
1164 retval = create_proc_exports_entry(); 1201 retval = create_proc_exports_entry();
1165 if (retval) 1202 if (retval)
1166 goto out_free_idmap; 1203 goto out_free_lockd;
1167 retval = register_filesystem(&nfsd_fs_type); 1204 retval = register_filesystem(&nfsd_fs_type);
1168 if (retval) 1205 if (retval)
1169 goto out_free_all; 1206 goto out_free_all;
@@ -1171,12 +1208,8 @@ static int __init init_nfsd(void)
1171out_free_all: 1208out_free_all:
1172 remove_proc_entry("fs/nfs/exports", NULL); 1209 remove_proc_entry("fs/nfs/exports", NULL);
1173 remove_proc_entry("fs/nfs", NULL); 1210 remove_proc_entry("fs/nfs", NULL);
1174out_free_idmap:
1175 nfsd_idmap_shutdown();
1176out_free_lockd: 1211out_free_lockd:
1177 nfsd_lockd_shutdown(); 1212 nfsd_lockd_shutdown();
1178 nfsd_export_shutdown();
1179out_free_cache:
1180 nfsd_reply_cache_shutdown(); 1213 nfsd_reply_cache_shutdown();
1181out_free_stat: 1214out_free_stat:
1182 nfsd_stat_shutdown(); 1215 nfsd_stat_shutdown();
@@ -1192,13 +1225,11 @@ out_unregister_notifier:
1192 1225
1193static void __exit exit_nfsd(void) 1226static void __exit exit_nfsd(void)
1194{ 1227{
1195 nfsd_export_shutdown();
1196 nfsd_reply_cache_shutdown(); 1228 nfsd_reply_cache_shutdown();
1197 remove_proc_entry("fs/nfs/exports", NULL); 1229 remove_proc_entry("fs/nfs/exports", NULL);
1198 remove_proc_entry("fs/nfs", NULL); 1230 remove_proc_entry("fs/nfs", NULL);
1199 nfsd_stat_shutdown(); 1231 nfsd_stat_shutdown();
1200 nfsd_lockd_shutdown(); 1232 nfsd_lockd_shutdown();
1201 nfsd_idmap_shutdown();
1202 nfsd4_free_slabs(); 1233 nfsd4_free_slabs();
1203 nfsd_fault_inject_cleanup(); 1234 nfsd_fault_inject_cleanup();
1204 unregister_filesystem(&nfsd_fs_type); 1235 unregister_filesystem(&nfsd_fs_type);
diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c
index 68454e75fce9..cc793005a87c 100644
--- a/fs/nfsd/nfsfh.c
+++ b/fs/nfsd/nfsfh.c
@@ -636,7 +636,7 @@ fh_put(struct svc_fh *fhp)
636#endif 636#endif
637 } 637 }
638 if (exp) { 638 if (exp) {
639 cache_put(&exp->h, &svc_export_cache); 639 exp_put(exp);
640 fhp->fh_export = NULL; 640 fhp->fh_export = NULL;
641 } 641 }
642 return; 642 return;
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index 28dfad39f0c5..ee709fc8f58b 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -11,6 +11,7 @@
11#include <linux/module.h> 11#include <linux/module.h>
12#include <linux/fs_struct.h> 12#include <linux/fs_struct.h>
13#include <linux/swap.h> 13#include <linux/swap.h>
14#include <linux/nsproxy.h>
14 15
15#include <linux/sunrpc/stats.h> 16#include <linux/sunrpc/stats.h>
16#include <linux/sunrpc/svcsock.h> 17#include <linux/sunrpc/svcsock.h>
@@ -220,7 +221,7 @@ static int nfsd_startup(unsigned short port, int nrservs)
220 ret = nfsd_init_socks(port); 221 ret = nfsd_init_socks(port);
221 if (ret) 222 if (ret)
222 goto out_racache; 223 goto out_racache;
223 ret = lockd_up(); 224 ret = lockd_up(&init_net);
224 if (ret) 225 if (ret)
225 goto out_racache; 226 goto out_racache;
226 ret = nfs4_state_start(); 227 ret = nfs4_state_start();
@@ -229,7 +230,7 @@ static int nfsd_startup(unsigned short port, int nrservs)
229 nfsd_up = true; 230 nfsd_up = true;
230 return 0; 231 return 0;
231out_lockd: 232out_lockd:
232 lockd_down(); 233 lockd_down(&init_net);
233out_racache: 234out_racache:
234 nfsd_racache_shutdown(); 235 nfsd_racache_shutdown();
235 return ret; 236 return ret;
@@ -246,7 +247,7 @@ static void nfsd_shutdown(void)
246 if (!nfsd_up) 247 if (!nfsd_up)
247 return; 248 return;
248 nfs4_state_shutdown(); 249 nfs4_state_shutdown();
249 lockd_down(); 250 lockd_down(&init_net);
250 nfsd_racache_shutdown(); 251 nfsd_racache_shutdown();
251 nfsd_up = false; 252 nfsd_up = false;
252} 253}
@@ -261,7 +262,7 @@ static void nfsd_last_thread(struct svc_serv *serv, struct net *net)
261 262
262 printk(KERN_WARNING "nfsd: last server has exited, flushing export " 263 printk(KERN_WARNING "nfsd: last server has exited, flushing export "
263 "cache\n"); 264 "cache\n");
264 nfsd_export_flush(); 265 nfsd_export_flush(net);
265} 266}
266 267
267void nfsd_reset_versions(void) 268void nfsd_reset_versions(void)
@@ -330,6 +331,8 @@ static int nfsd_get_default_max_blksize(void)
330 331
331int nfsd_create_serv(void) 332int nfsd_create_serv(void)
332{ 333{
334 int error;
335
333 WARN_ON(!mutex_is_locked(&nfsd_mutex)); 336 WARN_ON(!mutex_is_locked(&nfsd_mutex));
334 if (nfsd_serv) { 337 if (nfsd_serv) {
335 svc_get(nfsd_serv); 338 svc_get(nfsd_serv);
@@ -343,6 +346,12 @@ int nfsd_create_serv(void)
343 if (nfsd_serv == NULL) 346 if (nfsd_serv == NULL)
344 return -ENOMEM; 347 return -ENOMEM;
345 348
349 error = svc_bind(nfsd_serv, current->nsproxy->net_ns);
350 if (error < 0) {
351 svc_destroy(nfsd_serv);
352 return error;
353 }
354
346 set_max_drc(); 355 set_max_drc();
347 do_gettimeofday(&nfssvc_boot); /* record boot time */ 356 do_gettimeofday(&nfssvc_boot); /* record boot time */
348 return 0; 357 return 0;
@@ -373,6 +382,7 @@ int nfsd_set_nrthreads(int n, int *nthreads)
373 int i = 0; 382 int i = 0;
374 int tot = 0; 383 int tot = 0;
375 int err = 0; 384 int err = 0;
385 struct net *net = &init_net;
376 386
377 WARN_ON(!mutex_is_locked(&nfsd_mutex)); 387 WARN_ON(!mutex_is_locked(&nfsd_mutex));
378 388
@@ -417,6 +427,9 @@ int nfsd_set_nrthreads(int n, int *nthreads)
417 if (err) 427 if (err)
418 break; 428 break;
419 } 429 }
430
431 if (nfsd_serv->sv_nrthreads == 1)
432 svc_shutdown_net(nfsd_serv, net);
420 svc_destroy(nfsd_serv); 433 svc_destroy(nfsd_serv);
421 434
422 return err; 435 return err;
@@ -432,6 +445,7 @@ nfsd_svc(unsigned short port, int nrservs)
432{ 445{
433 int error; 446 int error;
434 bool nfsd_up_before; 447 bool nfsd_up_before;
448 struct net *net = &init_net;
435 449
436 mutex_lock(&nfsd_mutex); 450 mutex_lock(&nfsd_mutex);
437 dprintk("nfsd: creating service\n"); 451 dprintk("nfsd: creating service\n");
@@ -464,6 +478,8 @@ out_shutdown:
464 if (error < 0 && !nfsd_up_before) 478 if (error < 0 && !nfsd_up_before)
465 nfsd_shutdown(); 479 nfsd_shutdown();
466out_destroy: 480out_destroy:
481 if (nfsd_serv->sv_nrthreads == 1)
482 svc_shutdown_net(nfsd_serv, net);
467 svc_destroy(nfsd_serv); /* Release server */ 483 svc_destroy(nfsd_serv); /* Release server */
468out: 484out:
469 mutex_unlock(&nfsd_mutex); 485 mutex_unlock(&nfsd_mutex);
@@ -547,6 +563,9 @@ nfsd(void *vrqstp)
547 nfsdstats.th_cnt --; 563 nfsdstats.th_cnt --;
548 564
549out: 565out:
566 if (rqstp->rq_server->sv_nrthreads == 1)
567 svc_shutdown_net(rqstp->rq_server, &init_net);
568
550 /* Release the thread */ 569 /* Release the thread */
551 svc_exit_thread(rqstp); 570 svc_exit_thread(rqstp);
552 571
@@ -659,8 +678,12 @@ int nfsd_pool_stats_open(struct inode *inode, struct file *file)
659int nfsd_pool_stats_release(struct inode *inode, struct file *file) 678int nfsd_pool_stats_release(struct inode *inode, struct file *file)
660{ 679{
661 int ret = seq_release(inode, file); 680 int ret = seq_release(inode, file);
681 struct net *net = &init_net;
682
662 mutex_lock(&nfsd_mutex); 683 mutex_lock(&nfsd_mutex);
663 /* this function really, really should have been called svc_put() */ 684 /* this function really, really should have been called svc_put() */
685 if (nfsd_serv->sv_nrthreads == 1)
686 svc_shutdown_net(nfsd_serv, net);
664 svc_destroy(nfsd_serv); 687 svc_destroy(nfsd_serv);
665 mutex_unlock(&nfsd_mutex); 688 mutex_unlock(&nfsd_mutex);
666 return ret; 689 return ret;
diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h
index 89ab137d379a..849091e16ea6 100644
--- a/fs/nfsd/state.h
+++ b/fs/nfsd/state.h
@@ -232,7 +232,6 @@ struct nfs4_client {
232 time_t cl_time; /* time of last lease renewal */ 232 time_t cl_time; /* time of last lease renewal */
233 struct sockaddr_storage cl_addr; /* client ipaddress */ 233 struct sockaddr_storage cl_addr; /* client ipaddress */
234 u32 cl_flavor; /* setclientid pseudoflavor */ 234 u32 cl_flavor; /* setclientid pseudoflavor */
235 char *cl_principal; /* setclientid principal name */
236 struct svc_cred cl_cred; /* setclientid principal */ 235 struct svc_cred cl_cred; /* setclientid principal */
237 clientid_t cl_clientid; /* generated by server */ 236 clientid_t cl_clientid; /* generated by server */
238 nfs4_verifier cl_confirm; /* generated by server */ 237 nfs4_verifier cl_confirm; /* generated by server */
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 568666156ea4..c8bd9c3be7f7 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -2039,7 +2039,7 @@ nfsd_readdir(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t *offsetp,
2039 if (err) 2039 if (err)
2040 goto out; 2040 goto out;
2041 2041
2042 offset = vfs_llseek(file, offset, 0); 2042 offset = vfs_llseek(file, offset, SEEK_SET);
2043 if (offset < 0) { 2043 if (offset < 0) {
2044 err = nfserrno((int)offset); 2044 err = nfserrno((int)offset);
2045 goto out_close; 2045 goto out_close;
diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h
index 1b3501598ab5..acd127d4ee82 100644
--- a/fs/nfsd/xdr4.h
+++ b/fs/nfsd/xdr4.h
@@ -60,7 +60,7 @@ struct nfsd4_compound_state {
60 __be32 *datap; 60 __be32 *datap;
61 size_t iovlen; 61 size_t iovlen;
62 u32 minorversion; 62 u32 minorversion;
63 u32 status; 63 __be32 status;
64 stateid_t current_stateid; 64 stateid_t current_stateid;
65 stateid_t save_stateid; 65 stateid_t save_stateid;
66 /* to indicate current and saved state id presents */ 66 /* to indicate current and saved state id presents */
@@ -364,7 +364,7 @@ struct nfsd4_test_stateid_id {
364}; 364};
365 365
366struct nfsd4_test_stateid { 366struct nfsd4_test_stateid {
367 __be32 ts_num_ids; 367 u32 ts_num_ids;
368 struct list_head ts_stateid_list; 368 struct list_head ts_stateid_list;
369}; 369};
370 370
@@ -549,7 +549,7 @@ int nfs4svc_decode_compoundargs(struct svc_rqst *, __be32 *,
549 struct nfsd4_compoundargs *); 549 struct nfsd4_compoundargs *);
550int nfs4svc_encode_compoundres(struct svc_rqst *, __be32 *, 550int nfs4svc_encode_compoundres(struct svc_rqst *, __be32 *,
551 struct nfsd4_compoundres *); 551 struct nfsd4_compoundres *);
552int nfsd4_check_resp_size(struct nfsd4_compoundres *, u32); 552__be32 nfsd4_check_resp_size(struct nfsd4_compoundres *, u32);
553void nfsd4_encode_operation(struct nfsd4_compoundres *, struct nfsd4_op *); 553void nfsd4_encode_operation(struct nfsd4_compoundres *, struct nfsd4_op *);
554void nfsd4_encode_replay(struct nfsd4_compoundres *resp, struct nfsd4_op *op); 554void nfsd4_encode_replay(struct nfsd4_compoundres *resp, struct nfsd4_op *op);
555__be32 nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp, 555__be32 nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,