aboutsummaryrefslogtreecommitdiffstats
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
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 ...
-rw-r--r--fs/lockd/svc.c145
-rw-r--r--fs/nfs/callback.c13
-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
-rw-r--r--include/linux/sunrpc/svc.h2
-rw-r--r--include/linux/sunrpc/svcauth.h10
-rw-r--r--include/linux/sunrpc/svcauth_gss.h1
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_wrap.c61
-rw-r--r--net/sunrpc/auth_gss/svcauth_gss.c27
-rw-r--r--net/sunrpc/rpcb_clnt.c12
-rw-r--r--net/sunrpc/svc.c23
-rw-r--r--net/sunrpc/svc_xprt.c4
-rw-r--r--net/sunrpc/svcauth_unix.c6
23 files changed, 522 insertions, 435 deletions
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
index 1ead0750cdbb..80938fda67e0 100644
--- a/fs/lockd/svc.c
+++ b/fs/lockd/svc.c
@@ -251,39 +251,40 @@ out_err:
251 return err; 251 return err;
252} 252}
253 253
254static int lockd_up_net(struct net *net) 254static int lockd_up_net(struct svc_serv *serv, struct net *net)
255{ 255{
256 struct lockd_net *ln = net_generic(net, lockd_net_id); 256 struct lockd_net *ln = net_generic(net, lockd_net_id);
257 struct svc_serv *serv = nlmsvc_rqst->rq_server;
258 int error; 257 int error;
259 258
260 if (ln->nlmsvc_users) 259 if (ln->nlmsvc_users++)
261 return 0; 260 return 0;
262 261
263 error = svc_rpcb_setup(serv, net); 262 error = svc_bind(serv, net);
264 if (error) 263 if (error)
265 goto err_rpcb; 264 goto err_bind;
266 265
267 error = make_socks(serv, net); 266 error = make_socks(serv, net);
268 if (error < 0) 267 if (error < 0)
269 goto err_socks; 268 goto err_socks;
269 dprintk("lockd_up_net: per-net data created; net=%p\n", net);
270 return 0; 270 return 0;
271 271
272err_socks: 272err_socks:
273 svc_rpcb_cleanup(serv, net); 273 svc_rpcb_cleanup(serv, net);
274err_rpcb: 274err_bind:
275 ln->nlmsvc_users--;
275 return error; 276 return error;
276} 277}
277 278
278static void lockd_down_net(struct net *net) 279static void lockd_down_net(struct svc_serv *serv, struct net *net)
279{ 280{
280 struct lockd_net *ln = net_generic(net, lockd_net_id); 281 struct lockd_net *ln = net_generic(net, lockd_net_id);
281 struct svc_serv *serv = nlmsvc_rqst->rq_server;
282 282
283 if (ln->nlmsvc_users) { 283 if (ln->nlmsvc_users) {
284 if (--ln->nlmsvc_users == 0) { 284 if (--ln->nlmsvc_users == 0) {
285 nlm_shutdown_hosts_net(net); 285 nlm_shutdown_hosts_net(net);
286 svc_shutdown_net(serv, net); 286 svc_shutdown_net(serv, net);
287 dprintk("lockd_down_net: per-net data destroyed; net=%p\n", net);
287 } 288 }
288 } else { 289 } else {
289 printk(KERN_ERR "lockd_down_net: no users! task=%p, net=%p\n", 290 printk(KERN_ERR "lockd_down_net: no users! task=%p, net=%p\n",
@@ -292,21 +293,60 @@ static void lockd_down_net(struct net *net)
292 } 293 }
293} 294}
294 295
295/* 296static int lockd_start_svc(struct svc_serv *serv)
296 * Bring up the lockd process if it's not already up. 297{
297 */ 298 int error;
298int lockd_up(struct net *net) 299
300 if (nlmsvc_rqst)
301 return 0;
302
303 /*
304 * Create the kernel thread and wait for it to start.
305 */
306 nlmsvc_rqst = svc_prepare_thread(serv, &serv->sv_pools[0], NUMA_NO_NODE);
307 if (IS_ERR(nlmsvc_rqst)) {
308 error = PTR_ERR(nlmsvc_rqst);
309 printk(KERN_WARNING
310 "lockd_up: svc_rqst allocation failed, error=%d\n",
311 error);
312 goto out_rqst;
313 }
314
315 svc_sock_update_bufs(serv);
316 serv->sv_maxconn = nlm_max_connections;
317
318 nlmsvc_task = kthread_run(lockd, nlmsvc_rqst, serv->sv_name);
319 if (IS_ERR(nlmsvc_task)) {
320 error = PTR_ERR(nlmsvc_task);
321 printk(KERN_WARNING
322 "lockd_up: kthread_run failed, error=%d\n", error);
323 goto out_task;
324 }
325 dprintk("lockd_up: service started\n");
326 return 0;
327
328out_task:
329 svc_exit_thread(nlmsvc_rqst);
330 nlmsvc_task = NULL;
331out_rqst:
332 nlmsvc_rqst = NULL;
333 return error;
334}
335
336static struct svc_serv *lockd_create_svc(void)
299{ 337{
300 struct svc_serv *serv; 338 struct svc_serv *serv;
301 int error = 0;
302 339
303 mutex_lock(&nlmsvc_mutex);
304 /* 340 /*
305 * Check whether we're already up and running. 341 * Check whether we're already up and running.
306 */ 342 */
307 if (nlmsvc_rqst) { 343 if (nlmsvc_rqst) {
308 error = lockd_up_net(net); 344 /*
309 goto out; 345 * Note: increase service usage, because later in case of error
346 * svc_destroy() will be called.
347 */
348 svc_get(nlmsvc_rqst->rq_server);
349 return nlmsvc_rqst->rq_server;
310 } 350 }
311 351
312 /* 352 /*
@@ -317,59 +357,53 @@ int lockd_up(struct net *net)
317 printk(KERN_WARNING 357 printk(KERN_WARNING
318 "lockd_up: no pid, %d users??\n", nlmsvc_users); 358 "lockd_up: no pid, %d users??\n", nlmsvc_users);
319 359
320 error = -ENOMEM;
321 serv = svc_create(&nlmsvc_program, LOCKD_BUFSIZE, NULL); 360 serv = svc_create(&nlmsvc_program, LOCKD_BUFSIZE, NULL);
322 if (!serv) { 361 if (!serv) {
323 printk(KERN_WARNING "lockd_up: create service failed\n"); 362 printk(KERN_WARNING "lockd_up: create service failed\n");
324 goto out; 363 return ERR_PTR(-ENOMEM);
325 } 364 }
365 dprintk("lockd_up: service created\n");
366 return serv;
367}
326 368
327 error = make_socks(serv, net); 369/*
328 if (error < 0) 370 * Bring up the lockd process if it's not already up.
329 goto destroy_and_out; 371 */
372int lockd_up(struct net *net)
373{
374 struct svc_serv *serv;
375 int error;
330 376
331 /* 377 mutex_lock(&nlmsvc_mutex);
332 * Create the kernel thread and wait for it to start. 378
333 */ 379 serv = lockd_create_svc();
334 nlmsvc_rqst = svc_prepare_thread(serv, &serv->sv_pools[0], NUMA_NO_NODE); 380 if (IS_ERR(serv)) {
335 if (IS_ERR(nlmsvc_rqst)) { 381 error = PTR_ERR(serv);
336 error = PTR_ERR(nlmsvc_rqst); 382 goto err_create;
337 nlmsvc_rqst = NULL;
338 printk(KERN_WARNING
339 "lockd_up: svc_rqst allocation failed, error=%d\n",
340 error);
341 goto destroy_and_out;
342 } 383 }
343 384
344 svc_sock_update_bufs(serv); 385 error = lockd_up_net(serv, net);
345 serv->sv_maxconn = nlm_max_connections; 386 if (error < 0)
387 goto err_net;
346 388
347 nlmsvc_task = kthread_run(lockd, nlmsvc_rqst, serv->sv_name); 389 error = lockd_start_svc(serv);
348 if (IS_ERR(nlmsvc_task)) { 390 if (error < 0)
349 error = PTR_ERR(nlmsvc_task); 391 goto err_start;
350 svc_exit_thread(nlmsvc_rqst);
351 nlmsvc_task = NULL;
352 nlmsvc_rqst = NULL;
353 printk(KERN_WARNING
354 "lockd_up: kthread_run failed, error=%d\n", error);
355 goto destroy_and_out;
356 }
357 392
393 nlmsvc_users++;
358 /* 394 /*
359 * Note: svc_serv structures have an initial use count of 1, 395 * Note: svc_serv structures have an initial use count of 1,
360 * so we exit through here on both success and failure. 396 * so we exit through here on both success and failure.
361 */ 397 */
362destroy_and_out: 398err_net:
363 svc_destroy(serv); 399 svc_destroy(serv);
364out: 400err_create:
365 if (!error) {
366 struct lockd_net *ln = net_generic(net, lockd_net_id);
367
368 ln->nlmsvc_users++;
369 nlmsvc_users++;
370 }
371 mutex_unlock(&nlmsvc_mutex); 401 mutex_unlock(&nlmsvc_mutex);
372 return error; 402 return error;
403
404err_start:
405 lockd_down_net(serv, net);
406 goto err_net;
373} 407}
374EXPORT_SYMBOL_GPL(lockd_up); 408EXPORT_SYMBOL_GPL(lockd_up);
375 409
@@ -380,11 +414,10 @@ void
380lockd_down(struct net *net) 414lockd_down(struct net *net)
381{ 415{
382 mutex_lock(&nlmsvc_mutex); 416 mutex_lock(&nlmsvc_mutex);
417 lockd_down_net(nlmsvc_rqst->rq_server, net);
383 if (nlmsvc_users) { 418 if (nlmsvc_users) {
384 if (--nlmsvc_users) { 419 if (--nlmsvc_users)
385 lockd_down_net(net);
386 goto out; 420 goto out;
387 }
388 } else { 421 } else {
389 printk(KERN_ERR "lockd_down: no users! task=%p\n", 422 printk(KERN_ERR "lockd_down: no users! task=%p\n",
390 nlmsvc_task); 423 nlmsvc_task);
@@ -396,7 +429,9 @@ lockd_down(struct net *net)
396 BUG(); 429 BUG();
397 } 430 }
398 kthread_stop(nlmsvc_task); 431 kthread_stop(nlmsvc_task);
432 dprintk("lockd_down: service stopped\n");
399 svc_exit_thread(nlmsvc_rqst); 433 svc_exit_thread(nlmsvc_rqst);
434 dprintk("lockd_down: service destroyed\n");
400 nlmsvc_task = NULL; 435 nlmsvc_task = NULL;
401 nlmsvc_rqst = NULL; 436 nlmsvc_rqst = NULL;
402out: 437out:
diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c
index eb95f5091c1a..970659daa323 100644
--- a/fs/nfs/callback.c
+++ b/fs/nfs/callback.c
@@ -17,6 +17,7 @@
17#include <linux/kthread.h> 17#include <linux/kthread.h>
18#include <linux/sunrpc/svcauth_gss.h> 18#include <linux/sunrpc/svcauth_gss.h>
19#include <linux/sunrpc/bc_xprt.h> 19#include <linux/sunrpc/bc_xprt.h>
20#include <linux/nsproxy.h>
20 21
21#include <net/inet_sock.h> 22#include <net/inet_sock.h>
22 23
@@ -253,6 +254,7 @@ int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt)
253 char svc_name[12]; 254 char svc_name[12];
254 int ret = 0; 255 int ret = 0;
255 int minorversion_setup; 256 int minorversion_setup;
257 struct net *net = current->nsproxy->net_ns;
256 258
257 mutex_lock(&nfs_callback_mutex); 259 mutex_lock(&nfs_callback_mutex);
258 if (cb_info->users++ || cb_info->task != NULL) { 260 if (cb_info->users++ || cb_info->task != NULL) {
@@ -265,6 +267,12 @@ int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt)
265 goto out_err; 267 goto out_err;
266 } 268 }
267 269
270 ret = svc_bind(serv, net);
271 if (ret < 0) {
272 printk(KERN_WARNING "NFS: bind callback service failed\n");
273 goto out_err;
274 }
275
268 minorversion_setup = nfs_minorversion_callback_svc_setup(minorversion, 276 minorversion_setup = nfs_minorversion_callback_svc_setup(minorversion,
269 serv, xprt, &rqstp, &callback_svc); 277 serv, xprt, &rqstp, &callback_svc);
270 if (!minorversion_setup) { 278 if (!minorversion_setup) {
@@ -306,6 +314,8 @@ out_err:
306 dprintk("NFS: Couldn't create callback socket or server thread; " 314 dprintk("NFS: Couldn't create callback socket or server thread; "
307 "err = %d\n", ret); 315 "err = %d\n", ret);
308 cb_info->users--; 316 cb_info->users--;
317 if (serv)
318 svc_shutdown_net(serv, net);
309 goto out; 319 goto out;
310} 320}
311 321
@@ -320,6 +330,7 @@ void nfs_callback_down(int minorversion)
320 cb_info->users--; 330 cb_info->users--;
321 if (cb_info->users == 0 && cb_info->task != NULL) { 331 if (cb_info->users == 0 && cb_info->task != NULL) {
322 kthread_stop(cb_info->task); 332 kthread_stop(cb_info->task);
333 svc_shutdown_net(cb_info->serv, current->nsproxy->net_ns);
323 svc_exit_thread(cb_info->rqst); 334 svc_exit_thread(cb_info->rqst);
324 cb_info->serv = NULL; 335 cb_info->serv = NULL;
325 cb_info->rqst = NULL; 336 cb_info->rqst = NULL;
@@ -332,7 +343,7 @@ void nfs_callback_down(int minorversion)
332int 343int
333check_gss_callback_principal(struct nfs_client *clp, struct svc_rqst *rqstp) 344check_gss_callback_principal(struct nfs_client *clp, struct svc_rqst *rqstp)
334{ 345{
335 char *p = svc_gss_principal(rqstp); 346 char *p = rqstp->rq_cred.cr_principal;
336 347
337 if (rqstp->rq_authop->flavour != RPC_AUTH_GSS) 348 if (rqstp->rq_authop->flavour != RPC_AUTH_GSS)
338 return 1; 349 return 1;
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,
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
index 51b29ac45a8e..40e0a273faea 100644
--- a/include/linux/sunrpc/svc.h
+++ b/include/linux/sunrpc/svc.h
@@ -232,7 +232,6 @@ struct svc_rqst {
232 struct svc_pool * rq_pool; /* thread pool */ 232 struct svc_pool * rq_pool; /* thread pool */
233 struct svc_procedure * rq_procinfo; /* procedure info */ 233 struct svc_procedure * rq_procinfo; /* procedure info */
234 struct auth_ops * rq_authop; /* authentication flavour */ 234 struct auth_ops * rq_authop; /* authentication flavour */
235 u32 rq_flavor; /* pseudoflavor */
236 struct svc_cred rq_cred; /* auth info */ 235 struct svc_cred rq_cred; /* auth info */
237 void * rq_xprt_ctxt; /* transport specific context ptr */ 236 void * rq_xprt_ctxt; /* transport specific context ptr */
238 struct svc_deferred_req*rq_deferred; /* deferred request we are replaying */ 237 struct svc_deferred_req*rq_deferred; /* deferred request we are replaying */
@@ -416,6 +415,7 @@ struct svc_procedure {
416 */ 415 */
417int svc_rpcb_setup(struct svc_serv *serv, struct net *net); 416int svc_rpcb_setup(struct svc_serv *serv, struct net *net);
418void svc_rpcb_cleanup(struct svc_serv *serv, struct net *net); 417void svc_rpcb_cleanup(struct svc_serv *serv, struct net *net);
418int svc_bind(struct svc_serv *serv, struct net *net);
419struct svc_serv *svc_create(struct svc_program *, unsigned int, 419struct svc_serv *svc_create(struct svc_program *, unsigned int,
420 void (*shutdown)(struct svc_serv *, struct net *net)); 420 void (*shutdown)(struct svc_serv *, struct net *net));
421struct svc_rqst *svc_prepare_thread(struct svc_serv *serv, 421struct svc_rqst *svc_prepare_thread(struct svc_serv *serv,
diff --git a/include/linux/sunrpc/svcauth.h b/include/linux/sunrpc/svcauth.h
index 2c54683b91de..dd74084a9799 100644
--- a/include/linux/sunrpc/svcauth.h
+++ b/include/linux/sunrpc/svcauth.h
@@ -15,13 +15,23 @@
15#include <linux/sunrpc/msg_prot.h> 15#include <linux/sunrpc/msg_prot.h>
16#include <linux/sunrpc/cache.h> 16#include <linux/sunrpc/cache.h>
17#include <linux/hash.h> 17#include <linux/hash.h>
18#include <linux/cred.h>
18 19
19struct svc_cred { 20struct svc_cred {
20 uid_t cr_uid; 21 uid_t cr_uid;
21 gid_t cr_gid; 22 gid_t cr_gid;
22 struct group_info *cr_group_info; 23 struct group_info *cr_group_info;
24 u32 cr_flavor; /* pseudoflavor */
25 char *cr_principal; /* for gss */
23}; 26};
24 27
28static inline void free_svc_cred(struct svc_cred *cred)
29{
30 if (cred->cr_group_info)
31 put_group_info(cred->cr_group_info);
32 kfree(cred->cr_principal);
33}
34
25struct svc_rqst; /* forward decl */ 35struct svc_rqst; /* forward decl */
26struct in6_addr; 36struct in6_addr;
27 37
diff --git a/include/linux/sunrpc/svcauth_gss.h b/include/linux/sunrpc/svcauth_gss.h
index 7c32daa025eb..726aff1a5201 100644
--- a/include/linux/sunrpc/svcauth_gss.h
+++ b/include/linux/sunrpc/svcauth_gss.h
@@ -22,7 +22,6 @@ int gss_svc_init_net(struct net *net);
22void gss_svc_shutdown_net(struct net *net); 22void gss_svc_shutdown_net(struct net *net);
23int svcauth_gss_register_pseudoflavor(u32 pseudoflavor, char * name); 23int svcauth_gss_register_pseudoflavor(u32 pseudoflavor, char * name);
24u32 svcauth_gss_flavor(struct auth_domain *dom); 24u32 svcauth_gss_flavor(struct auth_domain *dom);
25char *svc_gss_principal(struct svc_rqst *);
26 25
27#endif /* __KERNEL__ */ 26#endif /* __KERNEL__ */
28#endif /* _LINUX_SUNRPC_SVCAUTH_GSS_H */ 27#endif /* _LINUX_SUNRPC_SVCAUTH_GSS_H */
diff --git a/net/sunrpc/auth_gss/gss_krb5_wrap.c b/net/sunrpc/auth_gss/gss_krb5_wrap.c
index 38f388c39dce..107c4528654f 100644
--- a/net/sunrpc/auth_gss/gss_krb5_wrap.c
+++ b/net/sunrpc/auth_gss/gss_krb5_wrap.c
@@ -381,21 +381,53 @@ gss_unwrap_kerberos_v1(struct krb5_ctx *kctx, int offset, struct xdr_buf *buf)
381} 381}
382 382
383/* 383/*
384 * We cannot currently handle tokens with rotated data. We need a 384 * We can shift data by up to LOCAL_BUF_LEN bytes in a pass. If we need
385 * generalized routine to rotate the data in place. It is anticipated 385 * to do more than that, we shift repeatedly. Kevin Coffman reports
386 * that we won't encounter rotated data in the general case. 386 * seeing 28 bytes as the value used by Microsoft clients and servers
387 * with AES, so this constant is chosen to allow handling 28 in one pass
388 * without using too much stack space.
389 *
390 * If that proves to a problem perhaps we could use a more clever
391 * algorithm.
387 */ 392 */
388static u32 393#define LOCAL_BUF_LEN 32u
389rotate_left(struct krb5_ctx *kctx, u32 offset, struct xdr_buf *buf, u16 rrc) 394
395static void rotate_buf_a_little(struct xdr_buf *buf, unsigned int shift)
390{ 396{
391 unsigned int realrrc = rrc % (buf->len - offset - GSS_KRB5_TOK_HDR_LEN); 397 char head[LOCAL_BUF_LEN];
398 char tmp[LOCAL_BUF_LEN];
399 unsigned int this_len, i;
400
401 BUG_ON(shift > LOCAL_BUF_LEN);
392 402
393 if (realrrc == 0) 403 read_bytes_from_xdr_buf(buf, 0, head, shift);
394 return 0; 404 for (i = 0; i + shift < buf->len; i += LOCAL_BUF_LEN) {
405 this_len = min(LOCAL_BUF_LEN, buf->len - (i + shift));
406 read_bytes_from_xdr_buf(buf, i+shift, tmp, this_len);
407 write_bytes_to_xdr_buf(buf, i, tmp, this_len);
408 }
409 write_bytes_to_xdr_buf(buf, buf->len - shift, head, shift);
410}
395 411
396 dprintk("%s: cannot process token with rotated data: " 412static void _rotate_left(struct xdr_buf *buf, unsigned int shift)
397 "rrc %u, realrrc %u\n", __func__, rrc, realrrc); 413{
398 return 1; 414 int shifted = 0;
415 int this_shift;
416
417 shift %= buf->len;
418 while (shifted < shift) {
419 this_shift = min(shift - shifted, LOCAL_BUF_LEN);
420 rotate_buf_a_little(buf, this_shift);
421 shifted += this_shift;
422 }
423}
424
425static void rotate_left(u32 base, struct xdr_buf *buf, unsigned int shift)
426{
427 struct xdr_buf subbuf;
428
429 xdr_buf_subsegment(buf, &subbuf, base, buf->len - base);
430 _rotate_left(&subbuf, shift);
399} 431}
400 432
401static u32 433static u32
@@ -495,11 +527,8 @@ gss_unwrap_kerberos_v2(struct krb5_ctx *kctx, int offset, struct xdr_buf *buf)
495 527
496 seqnum = be64_to_cpup((__be64 *)(ptr + 8)); 528 seqnum = be64_to_cpup((__be64 *)(ptr + 8));
497 529
498 if (rrc != 0) { 530 if (rrc != 0)
499 err = rotate_left(kctx, offset, buf, rrc); 531 rotate_left(offset + 16, buf, rrc);
500 if (err)
501 return GSS_S_FAILURE;
502 }
503 532
504 err = (*kctx->gk5e->decrypt_v2)(kctx, offset, buf, 533 err = (*kctx->gk5e->decrypt_v2)(kctx, offset, buf,
505 &headskip, &tailskip); 534 &headskip, &tailskip);
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
index 3089de37c433..73e957386600 100644
--- a/net/sunrpc/auth_gss/svcauth_gss.c
+++ b/net/sunrpc/auth_gss/svcauth_gss.c
@@ -336,7 +336,6 @@ struct rsc {
336 struct svc_cred cred; 336 struct svc_cred cred;
337 struct gss_svc_seq_data seqdata; 337 struct gss_svc_seq_data seqdata;
338 struct gss_ctx *mechctx; 338 struct gss_ctx *mechctx;
339 char *client_name;
340}; 339};
341 340
342static struct rsc *rsc_update(struct cache_detail *cd, struct rsc *new, struct rsc *old); 341static struct rsc *rsc_update(struct cache_detail *cd, struct rsc *new, struct rsc *old);
@@ -347,9 +346,7 @@ static void rsc_free(struct rsc *rsci)
347 kfree(rsci->handle.data); 346 kfree(rsci->handle.data);
348 if (rsci->mechctx) 347 if (rsci->mechctx)
349 gss_delete_sec_context(&rsci->mechctx); 348 gss_delete_sec_context(&rsci->mechctx);
350 if (rsci->cred.cr_group_info) 349 free_svc_cred(&rsci->cred);
351 put_group_info(rsci->cred.cr_group_info);
352 kfree(rsci->client_name);
353} 350}
354 351
355static void rsc_put(struct kref *ref) 352static void rsc_put(struct kref *ref)
@@ -387,7 +384,7 @@ rsc_init(struct cache_head *cnew, struct cache_head *ctmp)
387 tmp->handle.data = NULL; 384 tmp->handle.data = NULL;
388 new->mechctx = NULL; 385 new->mechctx = NULL;
389 new->cred.cr_group_info = NULL; 386 new->cred.cr_group_info = NULL;
390 new->client_name = NULL; 387 new->cred.cr_principal = NULL;
391} 388}
392 389
393static void 390static void
@@ -402,8 +399,8 @@ update_rsc(struct cache_head *cnew, struct cache_head *ctmp)
402 spin_lock_init(&new->seqdata.sd_lock); 399 spin_lock_init(&new->seqdata.sd_lock);
403 new->cred = tmp->cred; 400 new->cred = tmp->cred;
404 tmp->cred.cr_group_info = NULL; 401 tmp->cred.cr_group_info = NULL;
405 new->client_name = tmp->client_name; 402 new->cred.cr_principal = tmp->cred.cr_principal;
406 tmp->client_name = NULL; 403 tmp->cred.cr_principal = NULL;
407} 404}
408 405
409static struct cache_head * 406static struct cache_head *
@@ -501,8 +498,8 @@ static int rsc_parse(struct cache_detail *cd,
501 /* get client name */ 498 /* get client name */
502 len = qword_get(&mesg, buf, mlen); 499 len = qword_get(&mesg, buf, mlen);
503 if (len > 0) { 500 if (len > 0) {
504 rsci.client_name = kstrdup(buf, GFP_KERNEL); 501 rsci.cred.cr_principal = kstrdup(buf, GFP_KERNEL);
505 if (!rsci.client_name) 502 if (!rsci.cred.cr_principal)
506 goto out; 503 goto out;
507 } 504 }
508 505
@@ -932,16 +929,6 @@ struct gss_svc_data {
932 struct rsc *rsci; 929 struct rsc *rsci;
933}; 930};
934 931
935char *svc_gss_principal(struct svc_rqst *rqstp)
936{
937 struct gss_svc_data *gd = (struct gss_svc_data *)rqstp->rq_auth_data;
938
939 if (gd && gd->rsci)
940 return gd->rsci->client_name;
941 return NULL;
942}
943EXPORT_SYMBOL_GPL(svc_gss_principal);
944
945static int 932static int
946svcauth_gss_set_client(struct svc_rqst *rqstp) 933svcauth_gss_set_client(struct svc_rqst *rqstp)
947{ 934{
@@ -1220,7 +1207,7 @@ svcauth_gss_accept(struct svc_rqst *rqstp, __be32 *authp)
1220 } 1207 }
1221 svcdata->rsci = rsci; 1208 svcdata->rsci = rsci;
1222 cache_get(&rsci->h); 1209 cache_get(&rsci->h);
1223 rqstp->rq_flavor = gss_svc_to_pseudoflavor( 1210 rqstp->rq_cred.cr_flavor = gss_svc_to_pseudoflavor(
1224 rsci->mechctx->mech_type, gc->gc_svc); 1211 rsci->mechctx->mech_type, gc->gc_svc);
1225 ret = SVC_OK; 1212 ret = SVC_OK;
1226 goto out; 1213 goto out;
diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
index 3c0653439f3d..92509ffe15fc 100644
--- a/net/sunrpc/rpcb_clnt.c
+++ b/net/sunrpc/rpcb_clnt.c
@@ -180,14 +180,16 @@ void rpcb_put_local(struct net *net)
180 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); 180 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
181 struct rpc_clnt *clnt = sn->rpcb_local_clnt; 181 struct rpc_clnt *clnt = sn->rpcb_local_clnt;
182 struct rpc_clnt *clnt4 = sn->rpcb_local_clnt4; 182 struct rpc_clnt *clnt4 = sn->rpcb_local_clnt4;
183 int shutdown; 183 int shutdown = 0;
184 184
185 spin_lock(&sn->rpcb_clnt_lock); 185 spin_lock(&sn->rpcb_clnt_lock);
186 if (--sn->rpcb_users == 0) { 186 if (sn->rpcb_users) {
187 sn->rpcb_local_clnt = NULL; 187 if (--sn->rpcb_users == 0) {
188 sn->rpcb_local_clnt4 = NULL; 188 sn->rpcb_local_clnt = NULL;
189 sn->rpcb_local_clnt4 = NULL;
190 }
191 shutdown = !sn->rpcb_users;
189 } 192 }
190 shutdown = !sn->rpcb_users;
191 spin_unlock(&sn->rpcb_clnt_lock); 193 spin_unlock(&sn->rpcb_clnt_lock);
192 194
193 if (shutdown) { 195 if (shutdown) {
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index 017c0117d154..7e9baaa1e543 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -407,6 +407,14 @@ static int svc_uses_rpcbind(struct svc_serv *serv)
407 return 0; 407 return 0;
408} 408}
409 409
410int svc_bind(struct svc_serv *serv, struct net *net)
411{
412 if (!svc_uses_rpcbind(serv))
413 return 0;
414 return svc_rpcb_setup(serv, net);
415}
416EXPORT_SYMBOL_GPL(svc_bind);
417
410/* 418/*
411 * Create an RPC service 419 * Create an RPC service
412 */ 420 */
@@ -471,15 +479,8 @@ __svc_create(struct svc_program *prog, unsigned int bufsize, int npools,
471 spin_lock_init(&pool->sp_lock); 479 spin_lock_init(&pool->sp_lock);
472 } 480 }
473 481
474 if (svc_uses_rpcbind(serv)) { 482 if (svc_uses_rpcbind(serv) && (!serv->sv_shutdown))
475 if (svc_rpcb_setup(serv, current->nsproxy->net_ns) < 0) { 483 serv->sv_shutdown = svc_rpcb_cleanup;
476 kfree(serv->sv_pools);
477 kfree(serv);
478 return NULL;
479 }
480 if (!serv->sv_shutdown)
481 serv->sv_shutdown = svc_rpcb_cleanup;
482 }
483 484
484 return serv; 485 return serv;
485} 486}
@@ -536,8 +537,6 @@ EXPORT_SYMBOL_GPL(svc_shutdown_net);
536void 537void
537svc_destroy(struct svc_serv *serv) 538svc_destroy(struct svc_serv *serv)
538{ 539{
539 struct net *net = current->nsproxy->net_ns;
540
541 dprintk("svc: svc_destroy(%s, %d)\n", 540 dprintk("svc: svc_destroy(%s, %d)\n",
542 serv->sv_program->pg_name, 541 serv->sv_program->pg_name,
543 serv->sv_nrthreads); 542 serv->sv_nrthreads);
@@ -552,8 +551,6 @@ svc_destroy(struct svc_serv *serv)
552 551
553 del_timer_sync(&serv->sv_temptimer); 552 del_timer_sync(&serv->sv_temptimer);
554 553
555 svc_shutdown_net(serv, net);
556
557 /* 554 /*
558 * The last user is gone and thus all sockets have to be destroyed to 555 * The last user is gone and thus all sockets have to be destroyed to
559 * the point. Check this. 556 * the point. Check this.
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
index b98ee3514912..88f2bf671960 100644
--- a/net/sunrpc/svc_xprt.c
+++ b/net/sunrpc/svc_xprt.c
@@ -598,6 +598,7 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
598 598
599 /* now allocate needed pages. If we get a failure, sleep briefly */ 599 /* now allocate needed pages. If we get a failure, sleep briefly */
600 pages = (serv->sv_max_mesg + PAGE_SIZE) / PAGE_SIZE; 600 pages = (serv->sv_max_mesg + PAGE_SIZE) / PAGE_SIZE;
601 BUG_ON(pages >= RPCSVC_MAXPAGES);
601 for (i = 0; i < pages ; i++) 602 for (i = 0; i < pages ; i++)
602 while (rqstp->rq_pages[i] == NULL) { 603 while (rqstp->rq_pages[i] == NULL) {
603 struct page *p = alloc_page(GFP_KERNEL); 604 struct page *p = alloc_page(GFP_KERNEL);
@@ -612,7 +613,6 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
612 rqstp->rq_pages[i] = p; 613 rqstp->rq_pages[i] = p;
613 } 614 }
614 rqstp->rq_pages[i++] = NULL; /* this might be seen in nfs_read_actor */ 615 rqstp->rq_pages[i++] = NULL; /* this might be seen in nfs_read_actor */
615 BUG_ON(pages >= RPCSVC_MAXPAGES);
616 616
617 /* Make arg->head point to first page and arg->pages point to rest */ 617 /* Make arg->head point to first page and arg->pages point to rest */
618 arg = &rqstp->rq_arg; 618 arg = &rqstp->rq_arg;
@@ -973,7 +973,7 @@ void svc_close_net(struct svc_serv *serv, struct net *net)
973 svc_clear_pools(serv, net); 973 svc_clear_pools(serv, net);
974 /* 974 /*
975 * At this point the sp_sockets lists will stay empty, since 975 * At this point the sp_sockets lists will stay empty, since
976 * svc_enqueue will not add new entries without taking the 976 * svc_xprt_enqueue will not add new entries without taking the
977 * sp_lock and checking XPT_BUSY. 977 * sp_lock and checking XPT_BUSY.
978 */ 978 */
979 svc_clear_list(&serv->sv_tempsocks, net); 979 svc_clear_list(&serv->sv_tempsocks, net);
diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c
index 6138c925923d..2777fa896645 100644
--- a/net/sunrpc/svcauth_unix.c
+++ b/net/sunrpc/svcauth_unix.c
@@ -746,6 +746,7 @@ svcauth_null_accept(struct svc_rqst *rqstp, __be32 *authp)
746 struct svc_cred *cred = &rqstp->rq_cred; 746 struct svc_cred *cred = &rqstp->rq_cred;
747 747
748 cred->cr_group_info = NULL; 748 cred->cr_group_info = NULL;
749 cred->cr_principal = NULL;
749 rqstp->rq_client = NULL; 750 rqstp->rq_client = NULL;
750 751
751 if (argv->iov_len < 3*4) 752 if (argv->iov_len < 3*4)
@@ -773,7 +774,7 @@ svcauth_null_accept(struct svc_rqst *rqstp, __be32 *authp)
773 svc_putnl(resv, RPC_AUTH_NULL); 774 svc_putnl(resv, RPC_AUTH_NULL);
774 svc_putnl(resv, 0); 775 svc_putnl(resv, 0);
775 776
776 rqstp->rq_flavor = RPC_AUTH_NULL; 777 rqstp->rq_cred.cr_flavor = RPC_AUTH_NULL;
777 return SVC_OK; 778 return SVC_OK;
778} 779}
779 780
@@ -811,6 +812,7 @@ svcauth_unix_accept(struct svc_rqst *rqstp, __be32 *authp)
811 int len = argv->iov_len; 812 int len = argv->iov_len;
812 813
813 cred->cr_group_info = NULL; 814 cred->cr_group_info = NULL;
815 cred->cr_principal = NULL;
814 rqstp->rq_client = NULL; 816 rqstp->rq_client = NULL;
815 817
816 if ((len -= 3*4) < 0) 818 if ((len -= 3*4) < 0)
@@ -847,7 +849,7 @@ svcauth_unix_accept(struct svc_rqst *rqstp, __be32 *authp)
847 svc_putnl(resv, RPC_AUTH_NULL); 849 svc_putnl(resv, RPC_AUTH_NULL);
848 svc_putnl(resv, 0); 850 svc_putnl(resv, 0);
849 851
850 rqstp->rq_flavor = RPC_AUTH_UNIX; 852 rqstp->rq_cred.cr_flavor = RPC_AUTH_UNIX;
851 return SVC_OK; 853 return SVC_OK;
852 854
853badcred: 855badcred: