aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-06-01 11:32:58 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-06-01 11:32:58 -0400
commit419f4319495043a9507ac3e616be9ca60af09744 (patch)
tree0f747d80d11a6d4cd726ad6556839d5cd40b23ac /fs/nfsd
parentfb21affa49204acd409328415b49bfe90136653c (diff)
parent6eccece90b6addf80ef9e6db79b0bc873301034b (diff)
Merge branch 'for-3.5' of git://linux-nfs.org/~bfields/linux
Pull the rest of the nfsd commits from Bruce Fields: "... and then I cherry-picked the remainder of the patches from the head of my previous branch" This is the rest of the original nfsd branch, rebased without the delegation stuff that I thought really needed to be redone. I don't like rebasing things like this in general, but in this situation this was the lesser of two evils. * 'for-3.5' of git://linux-nfs.org/~bfields/linux: (50 commits) nfsd4: fix, consolidate client_has_state nfsd4: don't remove rebooted client record until confirmation nfsd4: remove some dprintk's and a comment nfsd4: return "real" sequence id in confirmed case nfsd4: fix exchange_id to return confirm flag nfsd4: clarify that renewing expired client is a bug nfsd4: simpler ordering of setclientid_confirm checks nfsd4: setclientid: remove pointless assignment nfsd4: fix error return in non-matching-creds case nfsd4: fix setclientid_confirm same_cred check nfsd4: merge 3 setclientid cases to 2 nfsd4: pull out common code from setclientid cases nfsd4: merge last two setclientid cases nfsd4: setclientid/confirm comment cleanup nfsd4: setclientid remove unnecessary terms from a logical expression nfsd4: move rq_flavor into svc_cred nfsd4: stricter cred comparison for setclientid/exchange_id nfsd4: move principal name into svc_cred nfsd4: allow removing clients not holding state nfsd4: rearrange exchange_id logic to simplify ...
Diffstat (limited to 'fs/nfsd')
-rw-r--r--fs/nfsd/auth.c2
-rw-r--r--fs/nfsd/export.c8
-rw-r--r--fs/nfsd/fault_inject.c1
-rw-r--r--fs/nfsd/nfs4callback.c5
-rw-r--r--fs/nfsd/nfs4idmap.c4
-rw-r--r--fs/nfsd/nfs4recover.c4
-rw-r--r--fs/nfsd/nfs4state.c525
-rw-r--r--fs/nfsd/nfs4xdr.c62
-rw-r--r--fs/nfsd/nfsctl.c12
-rw-r--r--fs/nfsd/nfssvc.c23
-rw-r--r--fs/nfsd/state.h1
-rw-r--r--fs/nfsd/xdr4.h6
12 files changed, 334 insertions, 319 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 dcb52b884519..ba233499b9a5 100644
--- a/fs/nfsd/export.c
+++ b/fs/nfsd/export.c
@@ -706,7 +706,7 @@ static struct cache_head *svc_export_alloc(void)
706 return NULL; 706 return NULL;
707} 707}
708 708
709struct cache_detail svc_export_cache_template = { 709static struct cache_detail svc_export_cache_template = {
710 .owner = THIS_MODULE, 710 .owner = THIS_MODULE,
711 .hash_size = EXPORT_HASHMAX, 711 .hash_size = EXPORT_HASHMAX,
712 .name = "nfsd.export", 712 .name = "nfsd.export",
@@ -904,13 +904,13 @@ __be32 check_nfsd_access(struct svc_export *exp, struct svc_rqst *rqstp)
904 return 0; 904 return 0;
905 /* ip-address based client; check sec= export option: */ 905 /* ip-address based client; check sec= export option: */
906 for (f = exp->ex_flavors; f < end; f++) { 906 for (f = exp->ex_flavors; f < end; f++) {
907 if (f->pseudoflavor == rqstp->rq_flavor) 907 if (f->pseudoflavor == rqstp->rq_cred.cr_flavor)
908 return 0; 908 return 0;
909 } 909 }
910 /* defaults in absence of sec= options: */ 910 /* defaults in absence of sec= options: */
911 if (exp->ex_nflavors == 0) { 911 if (exp->ex_nflavors == 0) {
912 if (rqstp->rq_flavor == RPC_AUTH_NULL || 912 if (rqstp->rq_cred.cr_flavor == RPC_AUTH_NULL ||
913 rqstp->rq_flavor == RPC_AUTH_UNIX) 913 rqstp->rq_cred.cr_flavor == RPC_AUTH_UNIX)
914 return 0; 914 return 0;
915 } 915 }
916 return nfserr_wrongsec; 916 return nfserr_wrongsec;
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/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 286a7f8f2024..dae36f1dee95 100644
--- a/fs/nfsd/nfs4idmap.c
+++ b/fs/nfsd/nfs4idmap.c
@@ -605,7 +605,7 @@ numeric_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namel
605static __be32 605static __be32
606do_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)
607{ 607{
608 if (nfs4_disable_idmapping && rqstp->rq_flavor < RPC_AUTH_GSS) 608 if (nfs4_disable_idmapping && rqstp->rq_cred.cr_flavor < RPC_AUTH_GSS)
609 if (numeric_name_to_id(rqstp, type, name, namelen, id)) 609 if (numeric_name_to_id(rqstp, type, name, namelen, id))
610 return 0; 610 return 0;
611 /* 611 /*
@@ -618,7 +618,7 @@ do_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen, u
618static int 618static int
619do_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)
620{ 620{
621 if (nfs4_disable_idmapping && rqstp->rq_flavor < RPC_AUTH_GSS) 621 if (nfs4_disable_idmapping && rqstp->rq_cred.cr_flavor < RPC_AUTH_GSS)
622 return sprintf(name, "%u", id); 622 return sprintf(name, "%u", id);
623 return idmap_id_to_name(rqstp, type, id, name); 623 return idmap_id_to_name(rqstp, type, id, name);
624} 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 03f82c0bc35d..8fdc9ec5c5d3 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}
@@ -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);
@@ -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}
@@ -3282,18 +3241,18 @@ STALE_STATEID(stateid_t *stateid)
3282} 3241}
3283 3242
3284static inline int 3243static inline int
3285access_permit_read(unsigned long access_bmap) 3244access_permit_read(struct nfs4_ol_stateid *stp)
3286{ 3245{
3287 return test_bit(NFS4_SHARE_ACCESS_READ, &access_bmap) || 3246 return test_access(NFS4_SHARE_ACCESS_READ, stp) ||
3288 test_bit(NFS4_SHARE_ACCESS_BOTH, &access_bmap) || 3247 test_access(NFS4_SHARE_ACCESS_BOTH, stp) ||
3289 test_bit(NFS4_SHARE_ACCESS_WRITE, &access_bmap); 3248 test_access(NFS4_SHARE_ACCESS_WRITE, stp);
3290} 3249}
3291 3250
3292static inline int 3251static inline int
3293access_permit_write(unsigned long access_bmap) 3252access_permit_write(struct nfs4_ol_stateid *stp)
3294{ 3253{
3295 return test_bit(NFS4_SHARE_ACCESS_WRITE, &access_bmap) || 3254 return test_access(NFS4_SHARE_ACCESS_WRITE, stp) ||
3296 test_bit(NFS4_SHARE_ACCESS_BOTH, &access_bmap); 3255 test_access(NFS4_SHARE_ACCESS_BOTH, stp);
3297} 3256}
3298 3257
3299static 3258static
@@ -3304,9 +3263,9 @@ __be32 nfs4_check_openmode(struct nfs4_ol_stateid *stp, int flags)
3304 /* 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: */
3305 if (stp->st_openstp) 3264 if (stp->st_openstp)
3306 stp = stp->st_openstp; 3265 stp = stp->st_openstp;
3307 if ((flags & WR_STATE) && (!access_permit_write(stp->st_access_bmap))) 3266 if ((flags & WR_STATE) && !access_permit_write(stp))
3308 goto out; 3267 goto out;
3309 if ((flags & RD_STATE) && (!access_permit_read(stp->st_access_bmap))) 3268 if ((flags & RD_STATE) && !access_permit_read(stp))
3310 goto out; 3269 goto out;
3311 status = nfs_ok; 3270 status = nfs_ok;
3312out: 3271out:
@@ -3346,7 +3305,7 @@ static bool stateid_generation_after(stateid_t *a, stateid_t *b)
3346 return (s32)a->si_generation - (s32)b->si_generation > 0; 3305 return (s32)a->si_generation - (s32)b->si_generation > 0;
3347} 3306}
3348 3307
3349static 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)
3350{ 3309{
3351 /* 3310 /*
3352 * When sessions are used the stateid generation number is ignored 3311 * When sessions are used the stateid generation number is ignored
@@ -3655,10 +3614,10 @@ out:
3655 3614
3656static 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)
3657{ 3616{
3658 if (!test_bit(access, &stp->st_access_bmap)) 3617 if (!test_access(access, stp))
3659 return; 3618 return;
3660 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));
3661 __clear_bit(access, &stp->st_access_bmap); 3620 clear_access(access, stp);
3662} 3621}
3663 3622
3664static 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)
@@ -3680,12 +3639,12 @@ static inline void nfs4_stateid_downgrade(struct nfs4_ol_stateid *stp, u32 to_ac
3680} 3639}
3681 3640
3682static void 3641static void
3683reset_union_bmap_deny(unsigned long deny, unsigned long *bmap) 3642reset_union_bmap_deny(unsigned long deny, struct nfs4_ol_stateid *stp)
3684{ 3643{
3685 int i; 3644 int i;
3686 for (i = 0; i < 4; i++) { 3645 for (i = 0; i < 4; i++) {
3687 if ((i & deny) != i) 3646 if ((i & deny) != i)
3688 __clear_bit(i, bmap); 3647 clear_deny(i, stp);
3689 } 3648 }
3690} 3649}
3691 3650
@@ -3712,19 +3671,19 @@ nfsd4_open_downgrade(struct svc_rqst *rqstp,
3712 if (status) 3671 if (status)
3713 goto out; 3672 goto out;
3714 status = nfserr_inval; 3673 status = nfserr_inval;
3715 if (!test_bit(od->od_share_access, &stp->st_access_bmap)) { 3674 if (!test_access(od->od_share_access, stp)) {
3716 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",
3717 stp->st_access_bmap, od->od_share_access); 3676 stp->st_access_bmap, od->od_share_access);
3718 goto out; 3677 goto out;
3719 } 3678 }
3720 if (!test_bit(od->od_share_deny, &stp->st_deny_bmap)) { 3679 if (!test_deny(od->od_share_deny, stp)) {
3721 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",
3722 stp->st_deny_bmap, od->od_share_deny); 3681 stp->st_deny_bmap, od->od_share_deny);
3723 goto out; 3682 goto out;
3724 } 3683 }
3725 nfs4_stateid_downgrade(stp, od->od_share_access); 3684 nfs4_stateid_downgrade(stp, od->od_share_access);
3726 3685
3727 reset_union_bmap_deny(od->od_share_deny, &stp->st_deny_bmap); 3686 reset_union_bmap_deny(od->od_share_deny, stp);
3728 3687
3729 update_stateid(&stp->st_stid.sc_stateid); 3688 update_stateid(&stp->st_stid.sc_stateid);
3730 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));
@@ -4014,13 +3973,13 @@ static void get_lock_access(struct nfs4_ol_stateid *lock_stp, u32 access)
4014 struct nfs4_file *fp = lock_stp->st_file; 3973 struct nfs4_file *fp = lock_stp->st_file;
4015 int oflag = nfs4_access_to_omode(access); 3974 int oflag = nfs4_access_to_omode(access);
4016 3975
4017 if (test_bit(access, &lock_stp->st_access_bmap)) 3976 if (test_access(access, lock_stp))
4018 return; 3977 return;
4019 nfs4_file_get_access(fp, oflag); 3978 nfs4_file_get_access(fp, oflag);
4020 __set_bit(access, &lock_stp->st_access_bmap); 3979 set_access(access, lock_stp);
4021} 3980}
4022 3981
4023__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)
4024{ 3983{
4025 struct nfs4_file *fi = ost->st_file; 3984 struct nfs4_file *fi = ost->st_file;
4026 struct nfs4_openowner *oo = openowner(ost->st_stateowner); 3985 struct nfs4_openowner *oo = openowner(ost->st_stateowner);
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 72699885ac48..c55298ed5772 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -661,6 +661,7 @@ static ssize_t __write_ports_addfd(char *buf)
661{ 661{
662 char *mesg = buf; 662 char *mesg = buf;
663 int fd, err; 663 int fd, err;
664 struct net *net = &init_net;
664 665
665 err = get_int(&mesg, &fd); 666 err = get_int(&mesg, &fd);
666 if (err != 0 || fd < 0) 667 if (err != 0 || fd < 0)
@@ -672,6 +673,8 @@ static ssize_t __write_ports_addfd(char *buf)
672 673
673 err = svc_addsock(nfsd_serv, fd, buf, SIMPLE_TRANSACTION_LIMIT); 674 err = svc_addsock(nfsd_serv, fd, buf, SIMPLE_TRANSACTION_LIMIT);
674 if (err < 0) { 675 if (err < 0) {
676 if (nfsd_serv->sv_nrthreads == 1)
677 svc_shutdown_net(nfsd_serv, net);
675 svc_destroy(nfsd_serv); 678 svc_destroy(nfsd_serv);
676 return err; 679 return err;
677 } 680 }
@@ -709,6 +712,7 @@ static ssize_t __write_ports_addxprt(char *buf)
709 char transport[16]; 712 char transport[16];
710 struct svc_xprt *xprt; 713 struct svc_xprt *xprt;
711 int port, err; 714 int port, err;
715 struct net *net = &init_net;
712 716
713 if (sscanf(buf, "%15s %4u", transport, &port) != 2) 717 if (sscanf(buf, "%15s %4u", transport, &port) != 2)
714 return -EINVAL; 718 return -EINVAL;
@@ -720,12 +724,12 @@ static ssize_t __write_ports_addxprt(char *buf)
720 if (err != 0) 724 if (err != 0)
721 return err; 725 return err;
722 726
723 err = svc_create_xprt(nfsd_serv, transport, &init_net, 727 err = svc_create_xprt(nfsd_serv, transport, net,
724 PF_INET, port, SVC_SOCK_ANONYMOUS); 728 PF_INET, port, SVC_SOCK_ANONYMOUS);
725 if (err < 0) 729 if (err < 0)
726 goto out_err; 730 goto out_err;
727 731
728 err = svc_create_xprt(nfsd_serv, transport, &init_net, 732 err = svc_create_xprt(nfsd_serv, transport, net,
729 PF_INET6, port, SVC_SOCK_ANONYMOUS); 733 PF_INET6, port, SVC_SOCK_ANONYMOUS);
730 if (err < 0 && err != -EAFNOSUPPORT) 734 if (err < 0 && err != -EAFNOSUPPORT)
731 goto out_close; 735 goto out_close;
@@ -734,12 +738,14 @@ static ssize_t __write_ports_addxprt(char *buf)
734 nfsd_serv->sv_nrthreads--; 738 nfsd_serv->sv_nrthreads--;
735 return 0; 739 return 0;
736out_close: 740out_close:
737 xprt = svc_find_xprt(nfsd_serv, transport, &init_net, PF_INET, port); 741 xprt = svc_find_xprt(nfsd_serv, transport, net, PF_INET, port);
738 if (xprt != NULL) { 742 if (xprt != NULL) {
739 svc_close_xprt(xprt); 743 svc_close_xprt(xprt);
740 svc_xprt_put(xprt); 744 svc_xprt_put(xprt);
741 } 745 }
742out_err: 746out_err:
747 if (nfsd_serv->sv_nrthreads == 1)
748 svc_shutdown_net(nfsd_serv, net);
743 svc_destroy(nfsd_serv); 749 svc_destroy(nfsd_serv);
744 return err; 750 return err;
745} 751}
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index cb4d51d8cbdb..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>
@@ -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/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,