aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nfs/Makefile6
-rw-r--r--fs/nfs/blocklayout/blocklayout.c3
-rw-r--r--fs/nfs/callback_proc.c2
-rw-r--r--fs/nfs/callback_xdr.c2
-rw-r--r--fs/nfs/client.c2
-rw-r--r--fs/nfs/dir.c26
-rw-r--r--fs/nfs/dns_resolve.c32
-rw-r--r--fs/nfs/idmap.c56
-rw-r--r--fs/nfs/inode.c27
-rw-r--r--fs/nfs/internal.h1
-rw-r--r--fs/nfs/mount_clnt.c14
-rw-r--r--fs/nfs/nfs4_fs.h2
-rw-r--r--fs/nfs/nfs4client.c6
-rw-r--r--fs/nfs/nfs4file.c1
-rw-r--r--fs/nfs/nfs4filelayout.c3
-rw-r--r--fs/nfs/nfs4filelayout.h3
-rw-r--r--fs/nfs/nfs4filelayoutdev.c8
-rw-r--r--fs/nfs/nfs4proc.c176
-rw-r--r--fs/nfs/nfs4session.c44
-rw-r--r--fs/nfs/nfs4session.h20
-rw-r--r--fs/nfs/nfs4state.c51
-rw-r--r--fs/nfs/nfs4super.c14
-rw-r--r--fs/nfs/nfs4xdr.c8
-rw-r--r--fs/nfs/objlayout/objlayout.c4
-rw-r--r--fs/nfs/pnfs.c42
-rw-r--r--fs/nfs/pnfs.h6
-rw-r--r--fs/nfs/super.c177
-rw-r--r--include/linux/nfs_fs.h1
-rw-r--r--include/linux/nfs_xdr.h1
-rw-r--r--include/linux/sunrpc/sched.h20
-rw-r--r--net/sunrpc/auth_gss/auth_gss.c62
-rw-r--r--net/sunrpc/clnt.c71
-rw-r--r--net/sunrpc/netns.h4
-rw-r--r--net/sunrpc/rpc_pipe.c13
-rw-r--r--net/sunrpc/sched.c27
35 files changed, 515 insertions, 420 deletions
diff --git a/fs/nfs/Makefile b/fs/nfs/Makefile
index cce2c057bd2d..e0bb048e9576 100644
--- a/fs/nfs/Makefile
+++ b/fs/nfs/Makefile
@@ -6,8 +6,7 @@ obj-$(CONFIG_NFS_FS) += nfs.o
6 6
7nfs-y := client.o dir.o file.o getroot.o inode.o super.o \ 7nfs-y := client.o dir.o file.o getroot.o inode.o super.o \
8 direct.o pagelist.o read.o symlink.o unlink.o \ 8 direct.o pagelist.o read.o symlink.o unlink.o \
9 write.o namespace.o mount_clnt.o \ 9 write.o namespace.o mount_clnt.o
10 dns_resolve.o cache_lib.o
11nfs-$(CONFIG_ROOT_NFS) += nfsroot.o 10nfs-$(CONFIG_ROOT_NFS) += nfsroot.o
12nfs-$(CONFIG_SYSCTL) += sysctl.o 11nfs-$(CONFIG_SYSCTL) += sysctl.o
13nfs-$(CONFIG_NFS_FSCACHE) += fscache.o fscache-index.o 12nfs-$(CONFIG_NFS_FSCACHE) += fscache.o fscache-index.o
@@ -22,7 +21,8 @@ nfsv3-$(CONFIG_NFS_V3_ACL) += nfs3acl.o
22obj-$(CONFIG_NFS_V4) += nfsv4.o 21obj-$(CONFIG_NFS_V4) += nfsv4.o
23nfsv4-y := nfs4proc.o nfs4xdr.o nfs4state.o nfs4renewd.o nfs4super.o nfs4file.o \ 22nfsv4-y := nfs4proc.o nfs4xdr.o nfs4state.o nfs4renewd.o nfs4super.o nfs4file.o \
24 delegation.o idmap.o callback.o callback_xdr.o callback_proc.o \ 23 delegation.o idmap.o callback.o callback_xdr.o callback_proc.o \
25 nfs4namespace.o nfs4getroot.o nfs4client.o 24 nfs4namespace.o nfs4getroot.o nfs4client.o dns_resolve.o
25nfsv4-$(CONFIG_NFS_USE_LEGACY_DNS) += cache_lib.o
26nfsv4-$(CONFIG_SYSCTL) += nfs4sysctl.o 26nfsv4-$(CONFIG_SYSCTL) += nfs4sysctl.o
27nfsv4-$(CONFIG_NFS_V4_1) += nfs4session.o pnfs.o pnfs_dev.o 27nfsv4-$(CONFIG_NFS_V4_1) += nfs4session.o pnfs.o pnfs_dev.o
28 28
diff --git a/fs/nfs/blocklayout/blocklayout.c b/fs/nfs/blocklayout/blocklayout.c
index 434b93ec0970..e242bbf72972 100644
--- a/fs/nfs/blocklayout/blocklayout.c
+++ b/fs/nfs/blocklayout/blocklayout.c
@@ -1089,9 +1089,10 @@ nfs4_blk_get_deviceinfo(struct nfs_server *server, const struct nfs_fh *fh,
1089 dev->pgbase = 0; 1089 dev->pgbase = 0;
1090 dev->pglen = PAGE_SIZE * max_pages; 1090 dev->pglen = PAGE_SIZE * max_pages;
1091 dev->mincount = 0; 1091 dev->mincount = 0;
1092 dev->maxcount = max_resp_sz - nfs41_maxgetdevinfo_overhead;
1092 1093
1093 dprintk("%s: dev_id: %s\n", __func__, dev->dev_id.data); 1094 dprintk("%s: dev_id: %s\n", __func__, dev->dev_id.data);
1094 rc = nfs4_proc_getdeviceinfo(server, dev); 1095 rc = nfs4_proc_getdeviceinfo(server, dev, NULL);
1095 dprintk("%s getdevice info returns %d\n", __func__, rc); 1096 dprintk("%s getdevice info returns %d\n", __func__, rc);
1096 if (rc) { 1097 if (rc) {
1097 rv = ERR_PTR(rc); 1098 rv = ERR_PTR(rc);
diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c
index 3d2af31e004c..e6ebc4c38c81 100644
--- a/fs/nfs/callback_proc.c
+++ b/fs/nfs/callback_proc.c
@@ -415,7 +415,7 @@ __be32 nfs4_callback_sequence(struct cb_sequenceargs *args,
415 415
416 spin_lock(&tbl->slot_tbl_lock); 416 spin_lock(&tbl->slot_tbl_lock);
417 /* state manager is resetting the session */ 417 /* state manager is resetting the session */
418 if (test_bit(NFS4_SESSION_DRAINING, &clp->cl_session->session_state)) { 418 if (test_bit(NFS4_SLOT_TBL_DRAINING, &tbl->slot_tbl_state)) {
419 spin_unlock(&tbl->slot_tbl_lock); 419 spin_unlock(&tbl->slot_tbl_lock);
420 status = htonl(NFS4ERR_DELAY); 420 status = htonl(NFS4ERR_DELAY);
421 /* Return NFS4ERR_BADSESSION if we're draining the session 421 /* Return NFS4ERR_BADSESSION if we're draining the session
diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c
index d450c21bc382..f4ccfe6521ec 100644
--- a/fs/nfs/callback_xdr.c
+++ b/fs/nfs/callback_xdr.c
@@ -763,7 +763,7 @@ static void nfs4_callback_free_slot(struct nfs4_session *session)
763 * A single slot, so highest used slotid is either 0 or -1 763 * A single slot, so highest used slotid is either 0 or -1
764 */ 764 */
765 tbl->highest_used_slotid = NFS4_NO_SLOT; 765 tbl->highest_used_slotid = NFS4_NO_SLOT;
766 nfs4_session_drain_complete(session, tbl); 766 nfs4_slot_tbl_drain_complete(tbl);
767 spin_unlock(&tbl->slot_tbl_lock); 767 spin_unlock(&tbl->slot_tbl_lock);
768} 768}
769 769
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index c426528deff4..340b1eff0267 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -753,8 +753,6 @@ static int nfs_init_server(struct nfs_server *server,
753 data->timeo, data->retrans); 753 data->timeo, data->retrans);
754 if (data->flags & NFS_MOUNT_NORESVPORT) 754 if (data->flags & NFS_MOUNT_NORESVPORT)
755 set_bit(NFS_CS_NORESVPORT, &cl_init.init_flags); 755 set_bit(NFS_CS_NORESVPORT, &cl_init.init_flags);
756 if (server->options & NFS_OPTION_MIGRATION)
757 set_bit(NFS_CS_MIGRATION, &cl_init.init_flags);
758 756
759 /* Allocate or find a client reference we can use */ 757 /* Allocate or find a client reference we can use */
760 clp = nfs_get_client(&cl_init, &timeparms, NULL, RPC_AUTH_UNIX); 758 clp = nfs_get_client(&cl_init, &timeparms, NULL, RPC_AUTH_UNIX);
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 743d3b524fc5..c3f21888654f 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -1385,18 +1385,6 @@ static int nfs_finish_open(struct nfs_open_context *ctx,
1385{ 1385{
1386 int err; 1386 int err;
1387 1387
1388 if (ctx->dentry != dentry) {
1389 dput(ctx->dentry);
1390 ctx->dentry = dget(dentry);
1391 }
1392
1393 /* If the open_intent is for execute, we have an extra check to make */
1394 if (ctx->mode & FMODE_EXEC) {
1395 err = nfs_may_open(dentry->d_inode, ctx->cred, open_flags);
1396 if (err < 0)
1397 goto out;
1398 }
1399
1400 err = finish_open(file, dentry, do_open, opened); 1388 err = finish_open(file, dentry, do_open, opened);
1401 if (err) 1389 if (err)
1402 goto out; 1390 goto out;
@@ -1455,13 +1443,13 @@ int nfs_atomic_open(struct inode *dir, struct dentry *dentry,
1455 1443
1456 nfs_block_sillyrename(dentry->d_parent); 1444 nfs_block_sillyrename(dentry->d_parent);
1457 inode = NFS_PROTO(dir)->open_context(dir, ctx, open_flags, &attr); 1445 inode = NFS_PROTO(dir)->open_context(dir, ctx, open_flags, &attr);
1458 d_drop(dentry); 1446 nfs_unblock_sillyrename(dentry->d_parent);
1459 if (IS_ERR(inode)) { 1447 if (IS_ERR(inode)) {
1460 nfs_unblock_sillyrename(dentry->d_parent);
1461 put_nfs_open_context(ctx); 1448 put_nfs_open_context(ctx);
1462 err = PTR_ERR(inode); 1449 err = PTR_ERR(inode);
1463 switch (err) { 1450 switch (err) {
1464 case -ENOENT: 1451 case -ENOENT:
1452 d_drop(dentry);
1465 d_add(dentry, NULL); 1453 d_add(dentry, NULL);
1466 break; 1454 break;
1467 case -EISDIR: 1455 case -EISDIR:
@@ -1477,16 +1465,8 @@ int nfs_atomic_open(struct inode *dir, struct dentry *dentry,
1477 } 1465 }
1478 goto out; 1466 goto out;
1479 } 1467 }
1480 res = d_add_unique(dentry, inode);
1481 if (res != NULL)
1482 dentry = res;
1483
1484 nfs_unblock_sillyrename(dentry->d_parent);
1485 nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
1486
1487 err = nfs_finish_open(ctx, dentry, file, open_flags, opened);
1488 1468
1489 dput(res); 1469 err = nfs_finish_open(ctx, ctx->dentry, file, open_flags, opened);
1490out: 1470out:
1491 return err; 1471 return err;
1492 1472
diff --git a/fs/nfs/dns_resolve.c b/fs/nfs/dns_resolve.c
index 945527092295..fc0f95ec7358 100644
--- a/fs/nfs/dns_resolve.c
+++ b/fs/nfs/dns_resolve.c
@@ -29,7 +29,6 @@ ssize_t nfs_dns_resolve_name(struct net *net, char *name, size_t namelen,
29 kfree(ip_addr); 29 kfree(ip_addr);
30 return ret; 30 return ret;
31} 31}
32EXPORT_SYMBOL_GPL(nfs_dns_resolve_name);
33 32
34#else 33#else
35 34
@@ -351,7 +350,6 @@ ssize_t nfs_dns_resolve_name(struct net *net, char *name,
351 ret = -ESRCH; 350 ret = -ESRCH;
352 return ret; 351 return ret;
353} 352}
354EXPORT_SYMBOL_GPL(nfs_dns_resolve_name);
355 353
356static struct cache_detail nfs_dns_resolve_template = { 354static struct cache_detail nfs_dns_resolve_template = {
357 .owner = THIS_MODULE, 355 .owner = THIS_MODULE,
@@ -396,6 +394,21 @@ void nfs_dns_resolver_cache_destroy(struct net *net)
396 cache_destroy_net(nn->nfs_dns_resolve, net); 394 cache_destroy_net(nn->nfs_dns_resolve, net);
397} 395}
398 396
397static int nfs4_dns_net_init(struct net *net)
398{
399 return nfs_dns_resolver_cache_init(net);
400}
401
402static void nfs4_dns_net_exit(struct net *net)
403{
404 nfs_dns_resolver_cache_destroy(net);
405}
406
407static struct pernet_operations nfs4_dns_resolver_ops = {
408 .init = nfs4_dns_net_init,
409 .exit = nfs4_dns_net_exit,
410};
411
399static int rpc_pipefs_event(struct notifier_block *nb, unsigned long event, 412static int rpc_pipefs_event(struct notifier_block *nb, unsigned long event,
400 void *ptr) 413 void *ptr)
401{ 414{
@@ -432,11 +445,24 @@ static struct notifier_block nfs_dns_resolver_block = {
432 445
433int nfs_dns_resolver_init(void) 446int nfs_dns_resolver_init(void)
434{ 447{
435 return rpc_pipefs_notifier_register(&nfs_dns_resolver_block); 448 int err;
449
450 err = register_pernet_subsys(&nfs4_dns_resolver_ops);
451 if (err < 0)
452 goto out;
453 err = rpc_pipefs_notifier_register(&nfs_dns_resolver_block);
454 if (err < 0)
455 goto out1;
456 return 0;
457out1:
458 unregister_pernet_subsys(&nfs4_dns_resolver_ops);
459out:
460 return err;
436} 461}
437 462
438void nfs_dns_resolver_destroy(void) 463void nfs_dns_resolver_destroy(void)
439{ 464{
440 rpc_pipefs_notifier_unregister(&nfs_dns_resolver_block); 465 rpc_pipefs_notifier_unregister(&nfs_dns_resolver_block);
466 unregister_pernet_subsys(&nfs4_dns_resolver_ops);
441} 467}
442#endif 468#endif
diff --git a/fs/nfs/idmap.c b/fs/nfs/idmap.c
index c516da5873fd..c2c4163d5683 100644
--- a/fs/nfs/idmap.c
+++ b/fs/nfs/idmap.c
@@ -262,29 +262,42 @@ static ssize_t nfs_idmap_get_desc(const char *name, size_t namelen,
262 return desclen; 262 return desclen;
263} 263}
264 264
265static ssize_t nfs_idmap_request_key(struct key_type *key_type, 265static struct key *nfs_idmap_request_key(const char *name, size_t namelen,
266 const char *name, size_t namelen, 266 const char *type, struct idmap *idmap)
267 const char *type, void *data,
268 size_t data_size, struct idmap *idmap)
269{ 267{
270 const struct cred *saved_cred;
271 struct key *rkey;
272 char *desc; 268 char *desc;
273 struct user_key_payload *payload; 269 struct key *rkey;
274 ssize_t ret; 270 ssize_t ret;
275 271
276 ret = nfs_idmap_get_desc(name, namelen, type, strlen(type), &desc); 272 ret = nfs_idmap_get_desc(name, namelen, type, strlen(type), &desc);
277 if (ret <= 0) 273 if (ret <= 0)
278 goto out; 274 return ERR_PTR(ret);
275
276 rkey = request_key(&key_type_id_resolver, desc, "");
277 if (IS_ERR(rkey)) {
278 mutex_lock(&idmap->idmap_mutex);
279 rkey = request_key_with_auxdata(&key_type_id_resolver_legacy,
280 desc, "", 0, idmap);
281 mutex_unlock(&idmap->idmap_mutex);
282 }
283
284 kfree(desc);
285 return rkey;
286}
287
288static ssize_t nfs_idmap_get_key(const char *name, size_t namelen,
289 const char *type, void *data,
290 size_t data_size, struct idmap *idmap)
291{
292 const struct cred *saved_cred;
293 struct key *rkey;
294 struct user_key_payload *payload;
295 ssize_t ret;
279 296
280 saved_cred = override_creds(id_resolver_cache); 297 saved_cred = override_creds(id_resolver_cache);
281 if (idmap) 298 rkey = nfs_idmap_request_key(name, namelen, type, idmap);
282 rkey = request_key_with_auxdata(key_type, desc, "", 0, idmap);
283 else
284 rkey = request_key(&key_type_id_resolver, desc, "");
285 revert_creds(saved_cred); 299 revert_creds(saved_cred);
286 300
287 kfree(desc);
288 if (IS_ERR(rkey)) { 301 if (IS_ERR(rkey)) {
289 ret = PTR_ERR(rkey); 302 ret = PTR_ERR(rkey);
290 goto out; 303 goto out;
@@ -316,23 +329,6 @@ out:
316 return ret; 329 return ret;
317} 330}
318 331
319static ssize_t nfs_idmap_get_key(const char *name, size_t namelen,
320 const char *type, void *data,
321 size_t data_size, struct idmap *idmap)
322{
323 ssize_t ret = nfs_idmap_request_key(&key_type_id_resolver,
324 name, namelen, type, data,
325 data_size, NULL);
326 if (ret < 0) {
327 mutex_lock(&idmap->idmap_mutex);
328 ret = nfs_idmap_request_key(&key_type_id_resolver_legacy,
329 name, namelen, type, data,
330 data_size, idmap);
331 mutex_unlock(&idmap->idmap_mutex);
332 }
333 return ret;
334}
335
336/* ID -> Name */ 332/* ID -> Name */
337static ssize_t nfs_idmap_lookup_name(__u32 id, const char *type, char *buf, 333static ssize_t nfs_idmap_lookup_name(__u32 id, const char *type, char *buf,
338 size_t buflen, struct idmap *idmap) 334 size_t buflen, struct idmap *idmap)
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index f908af672197..8ea62be3fefe 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -48,7 +48,6 @@
48#include "iostat.h" 48#include "iostat.h"
49#include "internal.h" 49#include "internal.h"
50#include "fscache.h" 50#include "fscache.h"
51#include "dns_resolve.h"
52#include "pnfs.h" 51#include "pnfs.h"
53#include "nfs.h" 52#include "nfs.h"
54#include "netns.h" 53#include "netns.h"
@@ -785,16 +784,23 @@ EXPORT_SYMBOL_GPL(put_nfs_open_context);
785 * Ensure that mmap has a recent RPC credential for use when writing out 784 * Ensure that mmap has a recent RPC credential for use when writing out
786 * shared pages 785 * shared pages
787 */ 786 */
788void nfs_file_set_open_context(struct file *filp, struct nfs_open_context *ctx) 787void nfs_inode_attach_open_context(struct nfs_open_context *ctx)
789{ 788{
790 struct inode *inode = file_inode(filp); 789 struct inode *inode = ctx->dentry->d_inode;
791 struct nfs_inode *nfsi = NFS_I(inode); 790 struct nfs_inode *nfsi = NFS_I(inode);
792 791
793 filp->private_data = get_nfs_open_context(ctx);
794 spin_lock(&inode->i_lock); 792 spin_lock(&inode->i_lock);
795 list_add(&ctx->list, &nfsi->open_files); 793 list_add(&ctx->list, &nfsi->open_files);
796 spin_unlock(&inode->i_lock); 794 spin_unlock(&inode->i_lock);
797} 795}
796EXPORT_SYMBOL_GPL(nfs_inode_attach_open_context);
797
798void nfs_file_set_open_context(struct file *filp, struct nfs_open_context *ctx)
799{
800 filp->private_data = get_nfs_open_context(ctx);
801 if (list_empty(&ctx->list))
802 nfs_inode_attach_open_context(ctx);
803}
798EXPORT_SYMBOL_GPL(nfs_file_set_open_context); 804EXPORT_SYMBOL_GPL(nfs_file_set_open_context);
799 805
800/* 806/*
@@ -820,10 +826,11 @@ struct nfs_open_context *nfs_find_open_context(struct inode *inode, struct rpc_c
820 826
821static void nfs_file_clear_open_context(struct file *filp) 827static void nfs_file_clear_open_context(struct file *filp)
822{ 828{
823 struct inode *inode = file_inode(filp);
824 struct nfs_open_context *ctx = nfs_file_open_context(filp); 829 struct nfs_open_context *ctx = nfs_file_open_context(filp);
825 830
826 if (ctx) { 831 if (ctx) {
832 struct inode *inode = ctx->dentry->d_inode;
833
827 filp->private_data = NULL; 834 filp->private_data = NULL;
828 spin_lock(&inode->i_lock); 835 spin_lock(&inode->i_lock);
829 list_move_tail(&ctx->list, &NFS_I(inode)->open_files); 836 list_move_tail(&ctx->list, &NFS_I(inode)->open_files);
@@ -1723,12 +1730,11 @@ EXPORT_SYMBOL_GPL(nfs_net_id);
1723static int nfs_net_init(struct net *net) 1730static int nfs_net_init(struct net *net)
1724{ 1731{
1725 nfs_clients_init(net); 1732 nfs_clients_init(net);
1726 return nfs_dns_resolver_cache_init(net); 1733 return 0;
1727} 1734}
1728 1735
1729static void nfs_net_exit(struct net *net) 1736static void nfs_net_exit(struct net *net)
1730{ 1737{
1731 nfs_dns_resolver_cache_destroy(net);
1732 nfs_cleanup_cb_ident_idr(net); 1738 nfs_cleanup_cb_ident_idr(net);
1733} 1739}
1734 1740
@@ -1746,10 +1752,6 @@ static int __init init_nfs_fs(void)
1746{ 1752{
1747 int err; 1753 int err;
1748 1754
1749 err = nfs_dns_resolver_init();
1750 if (err < 0)
1751 goto out10;;
1752
1753 err = register_pernet_subsys(&nfs_net_ops); 1755 err = register_pernet_subsys(&nfs_net_ops);
1754 if (err < 0) 1756 if (err < 0)
1755 goto out9; 1757 goto out9;
@@ -1815,8 +1817,6 @@ out7:
1815out8: 1817out8:
1816 unregister_pernet_subsys(&nfs_net_ops); 1818 unregister_pernet_subsys(&nfs_net_ops);
1817out9: 1819out9:
1818 nfs_dns_resolver_destroy();
1819out10:
1820 return err; 1820 return err;
1821} 1821}
1822 1822
@@ -1829,7 +1829,6 @@ static void __exit exit_nfs_fs(void)
1829 nfs_destroy_nfspagecache(); 1829 nfs_destroy_nfspagecache();
1830 nfs_fscache_unregister(); 1830 nfs_fscache_unregister();
1831 unregister_pernet_subsys(&nfs_net_ops); 1831 unregister_pernet_subsys(&nfs_net_ops);
1832 nfs_dns_resolver_destroy();
1833#ifdef CONFIG_PROC_FS 1832#ifdef CONFIG_PROC_FS
1834 rpc_proc_unregister(&init_net, "nfs"); 1833 rpc_proc_unregister(&init_net, "nfs");
1835#endif 1834#endif
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index 97ec2ef6a220..3c8373f90ab3 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -255,6 +255,7 @@ extern int nfs4_decode_dirent(struct xdr_stream *,
255#ifdef CONFIG_NFS_V4_1 255#ifdef CONFIG_NFS_V4_1
256extern const u32 nfs41_maxread_overhead; 256extern const u32 nfs41_maxread_overhead;
257extern const u32 nfs41_maxwrite_overhead; 257extern const u32 nfs41_maxwrite_overhead;
258extern const u32 nfs41_maxgetdevinfo_overhead;
258#endif 259#endif
259 260
260/* nfs4proc.c */ 261/* nfs4proc.c */
diff --git a/fs/nfs/mount_clnt.c b/fs/nfs/mount_clnt.c
index 91a6faf811ac..99a45283b9ee 100644
--- a/fs/nfs/mount_clnt.c
+++ b/fs/nfs/mount_clnt.c
@@ -139,7 +139,10 @@ struct mnt_fhstatus {
139 * nfs_mount - Obtain an NFS file handle for the given host and path 139 * nfs_mount - Obtain an NFS file handle for the given host and path
140 * @info: pointer to mount request arguments 140 * @info: pointer to mount request arguments
141 * 141 *
142 * Uses default timeout parameters specified by underlying transport. 142 * Uses default timeout parameters specified by underlying transport. On
143 * successful return, the auth_flavs list and auth_flav_len will be populated
144 * with the list from the server or a faked-up list if the server didn't
145 * provide one.
143 */ 146 */
144int nfs_mount(struct nfs_mount_request *info) 147int nfs_mount(struct nfs_mount_request *info)
145{ 148{
@@ -195,6 +198,15 @@ int nfs_mount(struct nfs_mount_request *info)
195 dprintk("NFS: MNT request succeeded\n"); 198 dprintk("NFS: MNT request succeeded\n");
196 status = 0; 199 status = 0;
197 200
201 /*
202 * If the server didn't provide a flavor list, allow the
203 * client to try any flavor.
204 */
205 if (info->version != NFS_MNT3_VERSION || *info->auth_flav_len == 0) {
206 dprintk("NFS: Faking up auth_flavs list\n");
207 info->auth_flavs[0] = RPC_AUTH_NULL;
208 *info->auth_flav_len = 1;
209 }
198out: 210out:
199 return status; 211 return status;
200 212
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index 283fd284bdb8..ee81e354bce7 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -194,7 +194,7 @@ struct nfs4_state_recovery_ops {
194 int (*recover_lock)(struct nfs4_state *, struct file_lock *); 194 int (*recover_lock)(struct nfs4_state *, struct file_lock *);
195 int (*establish_clid)(struct nfs_client *, struct rpc_cred *); 195 int (*establish_clid)(struct nfs_client *, struct rpc_cred *);
196 struct rpc_cred * (*get_clid_cred)(struct nfs_client *); 196 struct rpc_cred * (*get_clid_cred)(struct nfs_client *);
197 int (*reclaim_complete)(struct nfs_client *); 197 int (*reclaim_complete)(struct nfs_client *, struct rpc_cred *);
198 int (*detect_trunking)(struct nfs_client *, struct nfs_client **, 198 int (*detect_trunking)(struct nfs_client *, struct nfs_client **,
199 struct rpc_cred *); 199 struct rpc_cred *);
200}; 200};
diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c
index 18191919cc0b..90dce91dd5b5 100644
--- a/fs/nfs/nfs4client.c
+++ b/fs/nfs/nfs4client.c
@@ -208,7 +208,7 @@ struct nfs_client *nfs4_init_client(struct nfs_client *clp,
208 __set_bit(NFS_CS_DISCRTRY, &clp->cl_flags); 208 __set_bit(NFS_CS_DISCRTRY, &clp->cl_flags);
209 error = nfs_create_rpc_client(clp, timeparms, RPC_AUTH_GSS_KRB5I); 209 error = nfs_create_rpc_client(clp, timeparms, RPC_AUTH_GSS_KRB5I);
210 if (error == -EINVAL) 210 if (error == -EINVAL)
211 error = nfs_create_rpc_client(clp, timeparms, RPC_AUTH_NULL); 211 error = nfs_create_rpc_client(clp, timeparms, RPC_AUTH_UNIX);
212 if (error < 0) 212 if (error < 0)
213 goto error; 213 goto error;
214 214
@@ -631,6 +631,8 @@ static int nfs4_set_client(struct nfs_server *server,
631 631
632 if (server->flags & NFS_MOUNT_NORESVPORT) 632 if (server->flags & NFS_MOUNT_NORESVPORT)
633 set_bit(NFS_CS_NORESVPORT, &cl_init.init_flags); 633 set_bit(NFS_CS_NORESVPORT, &cl_init.init_flags);
634 if (server->options & NFS_OPTION_MIGRATION)
635 set_bit(NFS_CS_MIGRATION, &cl_init.init_flags);
634 636
635 /* Allocate or find a client reference we can use */ 637 /* Allocate or find a client reference we can use */
636 clp = nfs_get_client(&cl_init, timeparms, ip_addr, authflavour); 638 clp = nfs_get_client(&cl_init, timeparms, ip_addr, authflavour);
@@ -735,7 +737,7 @@ static int nfs4_server_common_setup(struct nfs_server *server,
735 return -ENOMEM; 737 return -ENOMEM;
736 738
737 /* We must ensure the session is initialised first */ 739 /* We must ensure the session is initialised first */
738 error = nfs4_init_session(server); 740 error = nfs4_init_session(server->nfs_client);
739 if (error < 0) 741 if (error < 0)
740 goto out; 742 goto out;
741 743
diff --git a/fs/nfs/nfs4file.c b/fs/nfs/nfs4file.c
index 13e6bb3e3fe5..e5b804dd944c 100644
--- a/fs/nfs/nfs4file.c
+++ b/fs/nfs/nfs4file.c
@@ -69,7 +69,6 @@ nfs4_file_open(struct inode *inode, struct file *filp)
69 goto out_drop; 69 goto out_drop;
70 } 70 }
71 } 71 }
72 iput(inode);
73 if (inode != dentry->d_inode) 72 if (inode != dentry->d_inode)
74 goto out_drop; 73 goto out_drop;
75 74
diff --git a/fs/nfs/nfs4filelayout.c b/fs/nfs/nfs4filelayout.c
index 22d10623f5ee..17ed87ef9de8 100644
--- a/fs/nfs/nfs4filelayout.c
+++ b/fs/nfs/nfs4filelayout.c
@@ -643,7 +643,8 @@ filelayout_check_layout(struct pnfs_layout_hdr *lo,
643 d = nfs4_find_get_deviceid(NFS_SERVER(lo->plh_inode)->pnfs_curr_ld, 643 d = nfs4_find_get_deviceid(NFS_SERVER(lo->plh_inode)->pnfs_curr_ld,
644 NFS_SERVER(lo->plh_inode)->nfs_client, id); 644 NFS_SERVER(lo->plh_inode)->nfs_client, id);
645 if (d == NULL) { 645 if (d == NULL) {
646 dsaddr = filelayout_get_device_info(lo->plh_inode, id, gfp_flags); 646 dsaddr = filelayout_get_device_info(lo->plh_inode, id,
647 lo->plh_lc_cred, gfp_flags);
647 if (dsaddr == NULL) 648 if (dsaddr == NULL)
648 goto out; 649 goto out;
649 } else 650 } else
diff --git a/fs/nfs/nfs4filelayout.h b/fs/nfs/nfs4filelayout.h
index 235ff952d3c8..cebd20e7e923 100644
--- a/fs/nfs/nfs4filelayout.h
+++ b/fs/nfs/nfs4filelayout.h
@@ -150,6 +150,7 @@ struct nfs4_pnfs_ds *nfs4_fl_prepare_ds(struct pnfs_layout_segment *lseg,
150extern void nfs4_fl_put_deviceid(struct nfs4_file_layout_dsaddr *dsaddr); 150extern void nfs4_fl_put_deviceid(struct nfs4_file_layout_dsaddr *dsaddr);
151extern void nfs4_fl_free_deviceid(struct nfs4_file_layout_dsaddr *dsaddr); 151extern void nfs4_fl_free_deviceid(struct nfs4_file_layout_dsaddr *dsaddr);
152struct nfs4_file_layout_dsaddr * 152struct nfs4_file_layout_dsaddr *
153filelayout_get_device_info(struct inode *inode, struct nfs4_deviceid *dev_id, gfp_t gfp_flags); 153filelayout_get_device_info(struct inode *inode, struct nfs4_deviceid *dev_id,
154 struct rpc_cred *cred, gfp_t gfp_flags);
154 155
155#endif /* FS_NFS_NFS4FILELAYOUT_H */ 156#endif /* FS_NFS_NFS4FILELAYOUT_H */
diff --git a/fs/nfs/nfs4filelayoutdev.c b/fs/nfs/nfs4filelayoutdev.c
index 661a0f611215..95604f64cab8 100644
--- a/fs/nfs/nfs4filelayoutdev.c
+++ b/fs/nfs/nfs4filelayoutdev.c
@@ -668,7 +668,10 @@ decode_and_add_device(struct inode *inode, struct pnfs_device *dev, gfp_t gfp_fl
668 * of available devices, and return it. 668 * of available devices, and return it.
669 */ 669 */
670struct nfs4_file_layout_dsaddr * 670struct nfs4_file_layout_dsaddr *
671filelayout_get_device_info(struct inode *inode, struct nfs4_deviceid *dev_id, gfp_t gfp_flags) 671filelayout_get_device_info(struct inode *inode,
672 struct nfs4_deviceid *dev_id,
673 struct rpc_cred *cred,
674 gfp_t gfp_flags)
672{ 675{
673 struct pnfs_device *pdev = NULL; 676 struct pnfs_device *pdev = NULL;
674 u32 max_resp_sz; 677 u32 max_resp_sz;
@@ -708,8 +711,9 @@ filelayout_get_device_info(struct inode *inode, struct nfs4_deviceid *dev_id, gf
708 pdev->pgbase = 0; 711 pdev->pgbase = 0;
709 pdev->pglen = max_resp_sz; 712 pdev->pglen = max_resp_sz;
710 pdev->mincount = 0; 713 pdev->mincount = 0;
714 pdev->maxcount = max_resp_sz - nfs41_maxgetdevinfo_overhead;
711 715
712 rc = nfs4_proc_getdeviceinfo(server, pdev); 716 rc = nfs4_proc_getdeviceinfo(server, pdev, cred);
713 dprintk("%s getdevice info returns %d\n", __func__, rc); 717 dprintk("%s getdevice info returns %d\n", __func__, rc);
714 if (rc) 718 if (rc)
715 goto out_free; 719 goto out_free;
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index c0d3123b6eba..d95616f140ad 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -84,8 +84,10 @@ static int nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred,
84 struct nfs4_state *state, struct nfs4_label *ilabel, 84 struct nfs4_state *state, struct nfs4_label *ilabel,
85 struct nfs4_label *olabel); 85 struct nfs4_label *olabel);
86#ifdef CONFIG_NFS_V4_1 86#ifdef CONFIG_NFS_V4_1
87static int nfs41_test_stateid(struct nfs_server *, nfs4_stateid *); 87static int nfs41_test_stateid(struct nfs_server *, nfs4_stateid *,
88static int nfs41_free_stateid(struct nfs_server *, nfs4_stateid *); 88 struct rpc_cred *);
89static int nfs41_free_stateid(struct nfs_server *, nfs4_stateid *,
90 struct rpc_cred *);
89#endif 91#endif
90 92
91#ifdef CONFIG_NFS_V4_SECURITY_LABEL 93#ifdef CONFIG_NFS_V4_SECURITY_LABEL
@@ -626,7 +628,7 @@ int nfs41_setup_sequence(struct nfs4_session *session,
626 task->tk_timeout = 0; 628 task->tk_timeout = 0;
627 629
628 spin_lock(&tbl->slot_tbl_lock); 630 spin_lock(&tbl->slot_tbl_lock);
629 if (test_bit(NFS4_SESSION_DRAINING, &session->session_state) && 631 if (test_bit(NFS4_SLOT_TBL_DRAINING, &tbl->slot_tbl_state) &&
630 !args->sa_privileged) { 632 !args->sa_privileged) {
631 /* The state manager will wait until the slot table is empty */ 633 /* The state manager will wait until the slot table is empty */
632 dprintk("%s session is draining\n", __func__); 634 dprintk("%s session is draining\n", __func__);
@@ -1147,7 +1149,7 @@ static struct nfs4_state *nfs4_try_open_cached(struct nfs4_opendata *opendata)
1147 struct nfs4_state *state = opendata->state; 1149 struct nfs4_state *state = opendata->state;
1148 struct nfs_inode *nfsi = NFS_I(state->inode); 1150 struct nfs_inode *nfsi = NFS_I(state->inode);
1149 struct nfs_delegation *delegation; 1151 struct nfs_delegation *delegation;
1150 int open_mode = opendata->o_arg.open_flags & (O_EXCL|O_TRUNC); 1152 int open_mode = opendata->o_arg.open_flags;
1151 fmode_t fmode = opendata->o_arg.fmode; 1153 fmode_t fmode = opendata->o_arg.fmode;
1152 nfs4_stateid stateid; 1154 nfs4_stateid stateid;
1153 int ret = -EAGAIN; 1155 int ret = -EAGAIN;
@@ -1926,18 +1928,30 @@ static void nfs41_clear_delegation_stateid(struct nfs4_state *state)
1926{ 1928{
1927 struct nfs_server *server = NFS_SERVER(state->inode); 1929 struct nfs_server *server = NFS_SERVER(state->inode);
1928 nfs4_stateid *stateid = &state->stateid; 1930 nfs4_stateid *stateid = &state->stateid;
1929 int status; 1931 struct nfs_delegation *delegation;
1932 struct rpc_cred *cred = NULL;
1933 int status = -NFS4ERR_BAD_STATEID;
1930 1934
1931 /* If a state reset has been done, test_stateid is unneeded */ 1935 /* If a state reset has been done, test_stateid is unneeded */
1932 if (test_bit(NFS_DELEGATED_STATE, &state->flags) == 0) 1936 if (test_bit(NFS_DELEGATED_STATE, &state->flags) == 0)
1933 return; 1937 return;
1934 1938
1935 status = nfs41_test_stateid(server, stateid); 1939 /* Get the delegation credential for use by test/free_stateid */
1940 rcu_read_lock();
1941 delegation = rcu_dereference(NFS_I(state->inode)->delegation);
1942 if (delegation != NULL &&
1943 nfs4_stateid_match(&delegation->stateid, stateid)) {
1944 cred = get_rpccred(delegation->cred);
1945 rcu_read_unlock();
1946 status = nfs41_test_stateid(server, stateid, cred);
1947 } else
1948 rcu_read_unlock();
1949
1936 if (status != NFS_OK) { 1950 if (status != NFS_OK) {
1937 /* Free the stateid unless the server explicitly 1951 /* Free the stateid unless the server explicitly
1938 * informs us the stateid is unrecognized. */ 1952 * informs us the stateid is unrecognized. */
1939 if (status != -NFS4ERR_BAD_STATEID) 1953 if (status != -NFS4ERR_BAD_STATEID)
1940 nfs41_free_stateid(server, stateid); 1954 nfs41_free_stateid(server, stateid, cred);
1941 nfs_remove_bad_delegation(state->inode); 1955 nfs_remove_bad_delegation(state->inode);
1942 1956
1943 write_seqlock(&state->seqlock); 1957 write_seqlock(&state->seqlock);
@@ -1945,6 +1959,9 @@ static void nfs41_clear_delegation_stateid(struct nfs4_state *state)
1945 write_sequnlock(&state->seqlock); 1959 write_sequnlock(&state->seqlock);
1946 clear_bit(NFS_DELEGATED_STATE, &state->flags); 1960 clear_bit(NFS_DELEGATED_STATE, &state->flags);
1947 } 1961 }
1962
1963 if (cred != NULL)
1964 put_rpccred(cred);
1948} 1965}
1949 1966
1950/** 1967/**
@@ -1959,6 +1976,7 @@ static int nfs41_check_open_stateid(struct nfs4_state *state)
1959{ 1976{
1960 struct nfs_server *server = NFS_SERVER(state->inode); 1977 struct nfs_server *server = NFS_SERVER(state->inode);
1961 nfs4_stateid *stateid = &state->open_stateid; 1978 nfs4_stateid *stateid = &state->open_stateid;
1979 struct rpc_cred *cred = state->owner->so_cred;
1962 int status; 1980 int status;
1963 1981
1964 /* If a state reset has been done, test_stateid is unneeded */ 1982 /* If a state reset has been done, test_stateid is unneeded */
@@ -1967,12 +1985,12 @@ static int nfs41_check_open_stateid(struct nfs4_state *state)
1967 (test_bit(NFS_O_RDWR_STATE, &state->flags) == 0)) 1985 (test_bit(NFS_O_RDWR_STATE, &state->flags) == 0))
1968 return -NFS4ERR_BAD_STATEID; 1986 return -NFS4ERR_BAD_STATEID;
1969 1987
1970 status = nfs41_test_stateid(server, stateid); 1988 status = nfs41_test_stateid(server, stateid, cred);
1971 if (status != NFS_OK) { 1989 if (status != NFS_OK) {
1972 /* Free the stateid unless the server explicitly 1990 /* Free the stateid unless the server explicitly
1973 * informs us the stateid is unrecognized. */ 1991 * informs us the stateid is unrecognized. */
1974 if (status != -NFS4ERR_BAD_STATEID) 1992 if (status != -NFS4ERR_BAD_STATEID)
1975 nfs41_free_stateid(server, stateid); 1993 nfs41_free_stateid(server, stateid, cred);
1976 1994
1977 clear_bit(NFS_O_RDONLY_STATE, &state->flags); 1995 clear_bit(NFS_O_RDONLY_STATE, &state->flags);
1978 clear_bit(NFS_O_WRONLY_STATE, &state->flags); 1996 clear_bit(NFS_O_WRONLY_STATE, &state->flags);
@@ -2013,10 +2031,11 @@ static inline void nfs4_exclusive_attrset(struct nfs4_opendata *opendata, struct
2013static int _nfs4_open_and_get_state(struct nfs4_opendata *opendata, 2031static int _nfs4_open_and_get_state(struct nfs4_opendata *opendata,
2014 fmode_t fmode, 2032 fmode_t fmode,
2015 int flags, 2033 int flags,
2016 struct nfs4_state **res) 2034 struct nfs_open_context *ctx)
2017{ 2035{
2018 struct nfs4_state_owner *sp = opendata->owner; 2036 struct nfs4_state_owner *sp = opendata->owner;
2019 struct nfs_server *server = sp->so_server; 2037 struct nfs_server *server = sp->so_server;
2038 struct dentry *dentry;
2020 struct nfs4_state *state; 2039 struct nfs4_state *state;
2021 unsigned int seq; 2040 unsigned int seq;
2022 int ret; 2041 int ret;
@@ -2034,13 +2053,31 @@ static int _nfs4_open_and_get_state(struct nfs4_opendata *opendata,
2034 if (server->caps & NFS_CAP_POSIX_LOCK) 2053 if (server->caps & NFS_CAP_POSIX_LOCK)
2035 set_bit(NFS_STATE_POSIX_LOCKS, &state->flags); 2054 set_bit(NFS_STATE_POSIX_LOCKS, &state->flags);
2036 2055
2056 dentry = opendata->dentry;
2057 if (dentry->d_inode == NULL) {
2058 /* FIXME: Is this d_drop() ever needed? */
2059 d_drop(dentry);
2060 dentry = d_add_unique(dentry, igrab(state->inode));
2061 if (dentry == NULL) {
2062 dentry = opendata->dentry;
2063 } else if (dentry != ctx->dentry) {
2064 dput(ctx->dentry);
2065 ctx->dentry = dget(dentry);
2066 }
2067 nfs_set_verifier(dentry,
2068 nfs_save_change_attribute(opendata->dir->d_inode));
2069 }
2070
2037 ret = nfs4_opendata_access(sp->so_cred, opendata, state, fmode, flags); 2071 ret = nfs4_opendata_access(sp->so_cred, opendata, state, fmode, flags);
2038 if (ret != 0) 2072 if (ret != 0)
2039 goto out; 2073 goto out;
2040 2074
2041 if (read_seqcount_retry(&sp->so_reclaim_seqcount, seq)) 2075 ctx->state = state;
2042 nfs4_schedule_stateid_recovery(server, state); 2076 if (dentry->d_inode == state->inode) {
2043 *res = state; 2077 nfs_inode_attach_open_context(ctx);
2078 if (read_seqcount_retry(&sp->so_reclaim_seqcount, seq))
2079 nfs4_schedule_stateid_recovery(server, state);
2080 }
2044out: 2081out:
2045 return ret; 2082 return ret;
2046} 2083}
@@ -2049,19 +2086,19 @@ out:
2049 * Returns a referenced nfs4_state 2086 * Returns a referenced nfs4_state
2050 */ 2087 */
2051static int _nfs4_do_open(struct inode *dir, 2088static int _nfs4_do_open(struct inode *dir,
2052 struct dentry *dentry, 2089 struct nfs_open_context *ctx,
2053 fmode_t fmode,
2054 int flags, 2090 int flags,
2055 struct iattr *sattr, 2091 struct iattr *sattr,
2056 struct nfs4_label *label, 2092 struct nfs4_label *label)
2057 struct rpc_cred *cred,
2058 struct nfs4_state **res,
2059 struct nfs4_threshold **ctx_th)
2060{ 2093{
2061 struct nfs4_state_owner *sp; 2094 struct nfs4_state_owner *sp;
2062 struct nfs4_state *state = NULL; 2095 struct nfs4_state *state = NULL;
2063 struct nfs_server *server = NFS_SERVER(dir); 2096 struct nfs_server *server = NFS_SERVER(dir);
2064 struct nfs4_opendata *opendata; 2097 struct nfs4_opendata *opendata;
2098 struct dentry *dentry = ctx->dentry;
2099 struct rpc_cred *cred = ctx->cred;
2100 struct nfs4_threshold **ctx_th = &ctx->mdsthreshold;
2101 fmode_t fmode = ctx->mode & (FMODE_READ|FMODE_WRITE|FMODE_EXEC);
2065 enum open_claim_type4 claim = NFS4_OPEN_CLAIM_NULL; 2102 enum open_claim_type4 claim = NFS4_OPEN_CLAIM_NULL;
2066 struct nfs4_label *olabel = NULL; 2103 struct nfs4_label *olabel = NULL;
2067 int status; 2104 int status;
@@ -2103,9 +2140,10 @@ static int _nfs4_do_open(struct inode *dir,
2103 if (dentry->d_inode != NULL) 2140 if (dentry->d_inode != NULL)
2104 opendata->state = nfs4_get_open_state(dentry->d_inode, sp); 2141 opendata->state = nfs4_get_open_state(dentry->d_inode, sp);
2105 2142
2106 status = _nfs4_open_and_get_state(opendata, fmode, flags, &state); 2143 status = _nfs4_open_and_get_state(opendata, fmode, flags, ctx);
2107 if (status != 0) 2144 if (status != 0)
2108 goto err_free_label; 2145 goto err_free_label;
2146 state = ctx->state;
2109 2147
2110 if ((opendata->o_arg.open_flags & O_EXCL) && 2148 if ((opendata->o_arg.open_flags & O_EXCL) &&
2111 (opendata->o_arg.createmode != NFS4_CREATE_GUARDED)) { 2149 (opendata->o_arg.createmode != NFS4_CREATE_GUARDED)) {
@@ -2132,7 +2170,6 @@ static int _nfs4_do_open(struct inode *dir,
2132 2170
2133 nfs4_opendata_put(opendata); 2171 nfs4_opendata_put(opendata);
2134 nfs4_put_state_owner(sp); 2172 nfs4_put_state_owner(sp);
2135 *res = state;
2136 return 0; 2173 return 0;
2137err_free_label: 2174err_free_label:
2138 nfs4_label_free(olabel); 2175 nfs4_label_free(olabel);
@@ -2142,29 +2179,24 @@ err_opendata_put:
2142err_put_state_owner: 2179err_put_state_owner:
2143 nfs4_put_state_owner(sp); 2180 nfs4_put_state_owner(sp);
2144out_err: 2181out_err:
2145 *res = NULL;
2146 return status; 2182 return status;
2147} 2183}
2148 2184
2149 2185
2150static struct nfs4_state *nfs4_do_open(struct inode *dir, 2186static struct nfs4_state *nfs4_do_open(struct inode *dir,
2151 struct dentry *dentry, 2187 struct nfs_open_context *ctx,
2152 fmode_t fmode,
2153 int flags, 2188 int flags,
2154 struct iattr *sattr, 2189 struct iattr *sattr,
2155 struct nfs4_label *label, 2190 struct nfs4_label *label)
2156 struct rpc_cred *cred,
2157 struct nfs4_threshold **ctx_th)
2158{ 2191{
2159 struct nfs_server *server = NFS_SERVER(dir); 2192 struct nfs_server *server = NFS_SERVER(dir);
2160 struct nfs4_exception exception = { }; 2193 struct nfs4_exception exception = { };
2161 struct nfs4_state *res; 2194 struct nfs4_state *res;
2162 int status; 2195 int status;
2163 2196
2164 fmode &= FMODE_READ|FMODE_WRITE|FMODE_EXEC;
2165 do { 2197 do {
2166 status = _nfs4_do_open(dir, dentry, fmode, flags, sattr, label, cred, 2198 status = _nfs4_do_open(dir, ctx, flags, sattr, label);
2167 &res, ctx_th); 2199 res = ctx->state;
2168 if (status == 0) 2200 if (status == 0)
2169 break; 2201 break;
2170 /* NOTE: BAD_SEQID means the server and client disagree about the 2202 /* NOTE: BAD_SEQID means the server and client disagree about the
@@ -2527,15 +2559,13 @@ nfs4_atomic_open(struct inode *dir, struct nfs_open_context *ctx, int open_flags
2527 label = nfs4_label_init_security(dir, ctx->dentry, attr, &l); 2559 label = nfs4_label_init_security(dir, ctx->dentry, attr, &l);
2528 2560
2529 /* Protect against concurrent sillydeletes */ 2561 /* Protect against concurrent sillydeletes */
2530 state = nfs4_do_open(dir, ctx->dentry, ctx->mode, open_flags, attr, label, 2562 state = nfs4_do_open(dir, ctx, open_flags, attr, label);
2531 ctx->cred, &ctx->mdsthreshold);
2532 2563
2533 nfs4_label_release_security(label); 2564 nfs4_label_release_security(label);
2534 2565
2535 if (IS_ERR(state)) 2566 if (IS_ERR(state))
2536 return ERR_CAST(state); 2567 return ERR_CAST(state);
2537 ctx->state = state; 2568 return state->inode;
2538 return igrab(state->inode);
2539} 2569}
2540 2570
2541static void nfs4_close_context(struct nfs_open_context *ctx, int is_sync) 2571static void nfs4_close_context(struct nfs_open_context *ctx, int is_sync)
@@ -3186,17 +3216,11 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
3186 ilabel = nfs4_label_init_security(dir, dentry, sattr, &l); 3216 ilabel = nfs4_label_init_security(dir, dentry, sattr, &l);
3187 3217
3188 sattr->ia_mode &= ~current_umask(); 3218 sattr->ia_mode &= ~current_umask();
3189 state = nfs4_do_open(dir, dentry, ctx->mode, 3219 state = nfs4_do_open(dir, ctx, flags, sattr, ilabel);
3190 flags, sattr, ilabel, ctx->cred,
3191 &ctx->mdsthreshold);
3192 d_drop(dentry);
3193 if (IS_ERR(state)) { 3220 if (IS_ERR(state)) {
3194 status = PTR_ERR(state); 3221 status = PTR_ERR(state);
3195 goto out; 3222 goto out;
3196 } 3223 }
3197 d_add(dentry, igrab(state->inode));
3198 nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
3199 ctx->state = state;
3200out: 3224out:
3201 nfs4_label_release_security(ilabel); 3225 nfs4_label_release_security(ilabel);
3202 put_nfs_open_context(ctx); 3226 put_nfs_open_context(ctx);
@@ -4690,7 +4714,7 @@ int nfs4_proc_setclientid(struct nfs_client *clp, u32 program,
4690 /* cb_client4 */ 4714 /* cb_client4 */
4691 rcu_read_lock(); 4715 rcu_read_lock();
4692 setclientid.sc_netid_len = scnprintf(setclientid.sc_netid, 4716 setclientid.sc_netid_len = scnprintf(setclientid.sc_netid,
4693 sizeof(setclientid.sc_netid), 4717 sizeof(setclientid.sc_netid), "%s",
4694 rpc_peeraddr2str(clp->cl_rpcclient, 4718 rpc_peeraddr2str(clp->cl_rpcclient,
4695 RPC_DISPLAY_NETID)); 4719 RPC_DISPLAY_NETID));
4696 rcu_read_unlock(); 4720 rcu_read_unlock();
@@ -5401,13 +5425,18 @@ static int nfs41_check_expired_locks(struct nfs4_state *state)
5401 5425
5402 list_for_each_entry(lsp, &state->lock_states, ls_locks) { 5426 list_for_each_entry(lsp, &state->lock_states, ls_locks) {
5403 if (test_bit(NFS_LOCK_INITIALIZED, &lsp->ls_flags)) { 5427 if (test_bit(NFS_LOCK_INITIALIZED, &lsp->ls_flags)) {
5404 status = nfs41_test_stateid(server, &lsp->ls_stateid); 5428 struct rpc_cred *cred = lsp->ls_state->owner->so_cred;
5429
5430 status = nfs41_test_stateid(server,
5431 &lsp->ls_stateid,
5432 cred);
5405 if (status != NFS_OK) { 5433 if (status != NFS_OK) {
5406 /* Free the stateid unless the server 5434 /* Free the stateid unless the server
5407 * informs us the stateid is unrecognized. */ 5435 * informs us the stateid is unrecognized. */
5408 if (status != -NFS4ERR_BAD_STATEID) 5436 if (status != -NFS4ERR_BAD_STATEID)
5409 nfs41_free_stateid(server, 5437 nfs41_free_stateid(server,
5410 &lsp->ls_stateid); 5438 &lsp->ls_stateid,
5439 cred);
5411 clear_bit(NFS_LOCK_INITIALIZED, &lsp->ls_flags); 5440 clear_bit(NFS_LOCK_INITIALIZED, &lsp->ls_flags);
5412 ret = status; 5441 ret = status;
5413 } 5442 }
@@ -5897,7 +5926,8 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
5897 struct nfs41_exchange_id_args args = { 5926 struct nfs41_exchange_id_args args = {
5898 .verifier = &verifier, 5927 .verifier = &verifier,
5899 .client = clp, 5928 .client = clp,
5900 .flags = EXCHGID4_FLAG_SUPP_MOVED_REFER, 5929 .flags = EXCHGID4_FLAG_SUPP_MOVED_REFER |
5930 EXCHGID4_FLAG_BIND_PRINC_STATEID,
5901 }; 5931 };
5902 struct nfs41_exchange_id_res res = { 5932 struct nfs41_exchange_id_res res = {
5903 0 5933 0
@@ -6154,17 +6184,14 @@ int nfs4_proc_get_lease_time(struct nfs_client *clp, struct nfs_fsinfo *fsinfo)
6154 */ 6184 */
6155static void nfs4_init_channel_attrs(struct nfs41_create_session_args *args) 6185static void nfs4_init_channel_attrs(struct nfs41_create_session_args *args)
6156{ 6186{
6157 struct nfs4_session *session = args->client->cl_session; 6187 unsigned int max_rqst_sz, max_resp_sz;
6158 unsigned int mxrqst_sz = session->fc_target_max_rqst_sz, 6188
6159 mxresp_sz = session->fc_target_max_resp_sz; 6189 max_rqst_sz = NFS_MAX_FILE_IO_SIZE + nfs41_maxwrite_overhead;
6190 max_resp_sz = NFS_MAX_FILE_IO_SIZE + nfs41_maxread_overhead;
6160 6191
6161 if (mxrqst_sz == 0)
6162 mxrqst_sz = NFS_MAX_FILE_IO_SIZE;
6163 if (mxresp_sz == 0)
6164 mxresp_sz = NFS_MAX_FILE_IO_SIZE;
6165 /* Fore channel attributes */ 6192 /* Fore channel attributes */
6166 args->fc_attrs.max_rqst_sz = mxrqst_sz; 6193 args->fc_attrs.max_rqst_sz = max_rqst_sz;
6167 args->fc_attrs.max_resp_sz = mxresp_sz; 6194 args->fc_attrs.max_resp_sz = max_resp_sz;
6168 args->fc_attrs.max_ops = NFS4_MAX_OPS; 6195 args->fc_attrs.max_ops = NFS4_MAX_OPS;
6169 args->fc_attrs.max_reqs = max_session_slots; 6196 args->fc_attrs.max_reqs = max_session_slots;
6170 6197
@@ -6551,12 +6578,14 @@ static const struct rpc_call_ops nfs4_reclaim_complete_call_ops = {
6551/* 6578/*
6552 * Issue a global reclaim complete. 6579 * Issue a global reclaim complete.
6553 */ 6580 */
6554static int nfs41_proc_reclaim_complete(struct nfs_client *clp) 6581static int nfs41_proc_reclaim_complete(struct nfs_client *clp,
6582 struct rpc_cred *cred)
6555{ 6583{
6556 struct nfs4_reclaim_complete_data *calldata; 6584 struct nfs4_reclaim_complete_data *calldata;
6557 struct rpc_task *task; 6585 struct rpc_task *task;
6558 struct rpc_message msg = { 6586 struct rpc_message msg = {
6559 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RECLAIM_COMPLETE], 6587 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RECLAIM_COMPLETE],
6588 .rpc_cred = cred,
6560 }; 6589 };
6561 struct rpc_task_setup task_setup_data = { 6590 struct rpc_task_setup task_setup_data = {
6562 .rpc_client = clp->cl_rpcclient, 6591 .rpc_client = clp->cl_rpcclient,
@@ -6740,6 +6769,7 @@ nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags)
6740 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LAYOUTGET], 6769 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LAYOUTGET],
6741 .rpc_argp = &lgp->args, 6770 .rpc_argp = &lgp->args,
6742 .rpc_resp = &lgp->res, 6771 .rpc_resp = &lgp->res,
6772 .rpc_cred = lgp->cred,
6743 }; 6773 };
6744 struct rpc_task_setup task_setup_data = { 6774 struct rpc_task_setup task_setup_data = {
6745 .rpc_client = server->client, 6775 .rpc_client = server->client,
@@ -6843,6 +6873,7 @@ int nfs4_proc_layoutreturn(struct nfs4_layoutreturn *lrp)
6843 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LAYOUTRETURN], 6873 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LAYOUTRETURN],
6844 .rpc_argp = &lrp->args, 6874 .rpc_argp = &lrp->args,
6845 .rpc_resp = &lrp->res, 6875 .rpc_resp = &lrp->res,
6876 .rpc_cred = lrp->cred,
6846 }; 6877 };
6847 struct rpc_task_setup task_setup_data = { 6878 struct rpc_task_setup task_setup_data = {
6848 .rpc_client = lrp->clp->cl_rpcclient, 6879 .rpc_client = lrp->clp->cl_rpcclient,
@@ -6912,7 +6943,9 @@ int nfs4_proc_getdevicelist(struct nfs_server *server,
6912EXPORT_SYMBOL_GPL(nfs4_proc_getdevicelist); 6943EXPORT_SYMBOL_GPL(nfs4_proc_getdevicelist);
6913 6944
6914static int 6945static int
6915_nfs4_proc_getdeviceinfo(struct nfs_server *server, struct pnfs_device *pdev) 6946_nfs4_proc_getdeviceinfo(struct nfs_server *server,
6947 struct pnfs_device *pdev,
6948 struct rpc_cred *cred)
6916{ 6949{
6917 struct nfs4_getdeviceinfo_args args = { 6950 struct nfs4_getdeviceinfo_args args = {
6918 .pdev = pdev, 6951 .pdev = pdev,
@@ -6924,6 +6957,7 @@ _nfs4_proc_getdeviceinfo(struct nfs_server *server, struct pnfs_device *pdev)
6924 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_GETDEVICEINFO], 6957 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_GETDEVICEINFO],
6925 .rpc_argp = &args, 6958 .rpc_argp = &args,
6926 .rpc_resp = &res, 6959 .rpc_resp = &res,
6960 .rpc_cred = cred,
6927 }; 6961 };
6928 int status; 6962 int status;
6929 6963
@@ -6934,14 +6968,16 @@ _nfs4_proc_getdeviceinfo(struct nfs_server *server, struct pnfs_device *pdev)
6934 return status; 6968 return status;
6935} 6969}
6936 6970
6937int nfs4_proc_getdeviceinfo(struct nfs_server *server, struct pnfs_device *pdev) 6971int nfs4_proc_getdeviceinfo(struct nfs_server *server,
6972 struct pnfs_device *pdev,
6973 struct rpc_cred *cred)
6938{ 6974{
6939 struct nfs4_exception exception = { }; 6975 struct nfs4_exception exception = { };
6940 int err; 6976 int err;
6941 6977
6942 do { 6978 do {
6943 err = nfs4_handle_exception(server, 6979 err = nfs4_handle_exception(server,
6944 _nfs4_proc_getdeviceinfo(server, pdev), 6980 _nfs4_proc_getdeviceinfo(server, pdev, cred),
6945 &exception); 6981 &exception);
6946 } while (exception.retry); 6982 } while (exception.retry);
6947 return err; 6983 return err;
@@ -7125,7 +7161,9 @@ out:
7125 return err; 7161 return err;
7126} 7162}
7127 7163
7128static int _nfs41_test_stateid(struct nfs_server *server, nfs4_stateid *stateid) 7164static int _nfs41_test_stateid(struct nfs_server *server,
7165 nfs4_stateid *stateid,
7166 struct rpc_cred *cred)
7129{ 7167{
7130 int status; 7168 int status;
7131 struct nfs41_test_stateid_args args = { 7169 struct nfs41_test_stateid_args args = {
@@ -7136,6 +7174,7 @@ static int _nfs41_test_stateid(struct nfs_server *server, nfs4_stateid *stateid)
7136 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_TEST_STATEID], 7174 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_TEST_STATEID],
7137 .rpc_argp = &args, 7175 .rpc_argp = &args,
7138 .rpc_resp = &res, 7176 .rpc_resp = &res,
7177 .rpc_cred = cred,
7139 }; 7178 };
7140 7179
7141 dprintk("NFS call test_stateid %p\n", stateid); 7180 dprintk("NFS call test_stateid %p\n", stateid);
@@ -7156,17 +7195,20 @@ static int _nfs41_test_stateid(struct nfs_server *server, nfs4_stateid *stateid)
7156 * 7195 *
7157 * @server: server / transport on which to perform the operation 7196 * @server: server / transport on which to perform the operation
7158 * @stateid: state ID to test 7197 * @stateid: state ID to test
7198 * @cred: credential
7159 * 7199 *
7160 * Returns NFS_OK if the server recognizes that "stateid" is valid. 7200 * Returns NFS_OK if the server recognizes that "stateid" is valid.
7161 * Otherwise a negative NFS4ERR value is returned if the operation 7201 * Otherwise a negative NFS4ERR value is returned if the operation
7162 * failed or the state ID is not currently valid. 7202 * failed or the state ID is not currently valid.
7163 */ 7203 */
7164static int nfs41_test_stateid(struct nfs_server *server, nfs4_stateid *stateid) 7204static int nfs41_test_stateid(struct nfs_server *server,
7205 nfs4_stateid *stateid,
7206 struct rpc_cred *cred)
7165{ 7207{
7166 struct nfs4_exception exception = { }; 7208 struct nfs4_exception exception = { };
7167 int err; 7209 int err;
7168 do { 7210 do {
7169 err = _nfs41_test_stateid(server, stateid); 7211 err = _nfs41_test_stateid(server, stateid, cred);
7170 if (err != -NFS4ERR_DELAY) 7212 if (err != -NFS4ERR_DELAY)
7171 break; 7213 break;
7172 nfs4_handle_exception(server, err, &exception); 7214 nfs4_handle_exception(server, err, &exception);
@@ -7215,10 +7257,12 @@ const struct rpc_call_ops nfs41_free_stateid_ops = {
7215 7257
7216static struct rpc_task *_nfs41_free_stateid(struct nfs_server *server, 7258static struct rpc_task *_nfs41_free_stateid(struct nfs_server *server,
7217 nfs4_stateid *stateid, 7259 nfs4_stateid *stateid,
7260 struct rpc_cred *cred,
7218 bool privileged) 7261 bool privileged)
7219{ 7262{
7220 struct rpc_message msg = { 7263 struct rpc_message msg = {
7221 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_FREE_STATEID], 7264 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_FREE_STATEID],
7265 .rpc_cred = cred,
7222 }; 7266 };
7223 struct rpc_task_setup task_setup = { 7267 struct rpc_task_setup task_setup = {
7224 .rpc_client = server->client, 7268 .rpc_client = server->client,
@@ -7251,16 +7295,19 @@ static struct rpc_task *_nfs41_free_stateid(struct nfs_server *server,
7251 * 7295 *
7252 * @server: server / transport on which to perform the operation 7296 * @server: server / transport on which to perform the operation
7253 * @stateid: state ID to release 7297 * @stateid: state ID to release
7298 * @cred: credential
7254 * 7299 *
7255 * Returns NFS_OK if the server freed "stateid". Otherwise a 7300 * Returns NFS_OK if the server freed "stateid". Otherwise a
7256 * negative NFS4ERR value is returned. 7301 * negative NFS4ERR value is returned.
7257 */ 7302 */
7258static int nfs41_free_stateid(struct nfs_server *server, nfs4_stateid *stateid) 7303static int nfs41_free_stateid(struct nfs_server *server,
7304 nfs4_stateid *stateid,
7305 struct rpc_cred *cred)
7259{ 7306{
7260 struct rpc_task *task; 7307 struct rpc_task *task;
7261 int ret; 7308 int ret;
7262 7309
7263 task = _nfs41_free_stateid(server, stateid, true); 7310 task = _nfs41_free_stateid(server, stateid, cred, true);
7264 if (IS_ERR(task)) 7311 if (IS_ERR(task))
7265 return PTR_ERR(task); 7312 return PTR_ERR(task);
7266 ret = rpc_wait_for_completion_task(task); 7313 ret = rpc_wait_for_completion_task(task);
@@ -7273,8 +7320,9 @@ static int nfs41_free_stateid(struct nfs_server *server, nfs4_stateid *stateid)
7273static int nfs41_free_lock_state(struct nfs_server *server, struct nfs4_lock_state *lsp) 7320static int nfs41_free_lock_state(struct nfs_server *server, struct nfs4_lock_state *lsp)
7274{ 7321{
7275 struct rpc_task *task; 7322 struct rpc_task *task;
7323 struct rpc_cred *cred = lsp->ls_state->owner->so_cred;
7276 7324
7277 task = _nfs41_free_stateid(server, &lsp->ls_stateid, false); 7325 task = _nfs41_free_stateid(server, &lsp->ls_stateid, cred, false);
7278 nfs4_free_lock_state(server, lsp); 7326 nfs4_free_lock_state(server, lsp);
7279 if (IS_ERR(task)) 7327 if (IS_ERR(task))
7280 return PTR_ERR(task); 7328 return PTR_ERR(task);
diff --git a/fs/nfs/nfs4session.c b/fs/nfs/nfs4session.c
index ebda5f4a031b..36e21cb29d65 100644
--- a/fs/nfs/nfs4session.c
+++ b/fs/nfs/nfs4session.c
@@ -73,7 +73,7 @@ void nfs4_free_slot(struct nfs4_slot_table *tbl, struct nfs4_slot *slot)
73 tbl->highest_used_slotid = new_max; 73 tbl->highest_used_slotid = new_max;
74 else { 74 else {
75 tbl->highest_used_slotid = NFS4_NO_SLOT; 75 tbl->highest_used_slotid = NFS4_NO_SLOT;
76 nfs4_session_drain_complete(tbl->session, tbl); 76 nfs4_slot_tbl_drain_complete(tbl);
77 } 77 }
78 } 78 }
79 dprintk("%s: slotid %u highest_used_slotid %d\n", __func__, 79 dprintk("%s: slotid %u highest_used_slotid %d\n", __func__,
@@ -226,7 +226,7 @@ static bool nfs41_assign_slot(struct rpc_task *task, void *pslot)
226 struct nfs4_slot *slot = pslot; 226 struct nfs4_slot *slot = pslot;
227 struct nfs4_slot_table *tbl = slot->table; 227 struct nfs4_slot_table *tbl = slot->table;
228 228
229 if (nfs4_session_draining(tbl->session) && !args->sa_privileged) 229 if (nfs4_slot_tbl_draining(tbl) && !args->sa_privileged)
230 return false; 230 return false;
231 slot->generation = tbl->generation; 231 slot->generation = tbl->generation;
232 args->sa_slot = slot; 232 args->sa_slot = slot;
@@ -478,48 +478,12 @@ static int nfs41_check_session_ready(struct nfs_client *clp)
478 return 0; 478 return 0;
479} 479}
480 480
481int nfs4_init_session(struct nfs_server *server) 481int nfs4_init_session(struct nfs_client *clp)
482{ 482{
483 struct nfs_client *clp = server->nfs_client;
484 struct nfs4_session *session;
485 unsigned int target_max_rqst_sz = NFS_MAX_FILE_IO_SIZE;
486 unsigned int target_max_resp_sz = NFS_MAX_FILE_IO_SIZE;
487
488 if (!nfs4_has_session(clp)) 483 if (!nfs4_has_session(clp))
489 return 0; 484 return 0;
490 485
491 if (server->rsize != 0) 486 clear_bit(NFS4_SESSION_INITING, &clp->cl_session->session_state);
492 target_max_resp_sz = server->rsize;
493 target_max_resp_sz += nfs41_maxread_overhead;
494
495 if (server->wsize != 0)
496 target_max_rqst_sz = server->wsize;
497 target_max_rqst_sz += nfs41_maxwrite_overhead;
498
499 session = clp->cl_session;
500 spin_lock(&clp->cl_lock);
501 if (test_and_clear_bit(NFS4_SESSION_INITING, &session->session_state)) {
502 /* Initialise targets and channel attributes */
503 session->fc_target_max_rqst_sz = target_max_rqst_sz;
504 session->fc_attrs.max_rqst_sz = target_max_rqst_sz;
505 session->fc_target_max_resp_sz = target_max_resp_sz;
506 session->fc_attrs.max_resp_sz = target_max_resp_sz;
507 } else {
508 /* Just adjust the targets */
509 if (target_max_rqst_sz > session->fc_target_max_rqst_sz) {
510 session->fc_target_max_rqst_sz = target_max_rqst_sz;
511 set_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state);
512 }
513 if (target_max_resp_sz > session->fc_target_max_resp_sz) {
514 session->fc_target_max_resp_sz = target_max_resp_sz;
515 set_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state);
516 }
517 }
518 spin_unlock(&clp->cl_lock);
519
520 if (test_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state))
521 nfs4_schedule_lease_recovery(clp);
522
523 return nfs41_check_session_ready(clp); 487 return nfs41_check_session_ready(clp);
524} 488}
525 489
diff --git a/fs/nfs/nfs4session.h b/fs/nfs/nfs4session.h
index 6f3cb39386d4..3a153d82b90c 100644
--- a/fs/nfs/nfs4session.h
+++ b/fs/nfs/nfs4session.h
@@ -25,6 +25,10 @@ struct nfs4_slot {
25}; 25};
26 26
27/* Sessions */ 27/* Sessions */
28enum nfs4_slot_tbl_state {
29 NFS4_SLOT_TBL_DRAINING,
30};
31
28#define SLOT_TABLE_SZ DIV_ROUND_UP(NFS4_MAX_SLOT_TABLE, 8*sizeof(long)) 32#define SLOT_TABLE_SZ DIV_ROUND_UP(NFS4_MAX_SLOT_TABLE, 8*sizeof(long))
29struct nfs4_slot_table { 33struct nfs4_slot_table {
30 struct nfs4_session *session; /* Parent session */ 34 struct nfs4_session *session; /* Parent session */
@@ -43,6 +47,7 @@ struct nfs4_slot_table {
43 unsigned long generation; /* Generation counter for 47 unsigned long generation; /* Generation counter for
44 target_highest_slotid */ 48 target_highest_slotid */
45 struct completion complete; 49 struct completion complete;
50 unsigned long slot_tbl_state;
46}; 51};
47 52
48/* 53/*
@@ -61,14 +66,10 @@ struct nfs4_session {
61 struct nfs4_channel_attrs bc_attrs; 66 struct nfs4_channel_attrs bc_attrs;
62 struct nfs4_slot_table bc_slot_table; 67 struct nfs4_slot_table bc_slot_table;
63 struct nfs_client *clp; 68 struct nfs_client *clp;
64 /* Create session arguments */
65 unsigned int fc_target_max_rqst_sz;
66 unsigned int fc_target_max_resp_sz;
67}; 69};
68 70
69enum nfs4_session_state { 71enum nfs4_session_state {
70 NFS4_SESSION_INITING, 72 NFS4_SESSION_INITING,
71 NFS4_SESSION_DRAINING,
72}; 73};
73 74
74#if defined(CONFIG_NFS_V4_1) 75#if defined(CONFIG_NFS_V4_1)
@@ -85,15 +86,14 @@ extern int nfs4_setup_session_slot_tables(struct nfs4_session *ses);
85 86
86extern struct nfs4_session *nfs4_alloc_session(struct nfs_client *clp); 87extern struct nfs4_session *nfs4_alloc_session(struct nfs_client *clp);
87extern void nfs4_destroy_session(struct nfs4_session *session); 88extern void nfs4_destroy_session(struct nfs4_session *session);
88extern int nfs4_init_session(struct nfs_server *server); 89extern int nfs4_init_session(struct nfs_client *clp);
89extern int nfs4_init_ds_session(struct nfs_client *, unsigned long); 90extern int nfs4_init_ds_session(struct nfs_client *, unsigned long);
90 91
91extern void nfs4_session_drain_complete(struct nfs4_session *session, 92extern void nfs4_slot_tbl_drain_complete(struct nfs4_slot_table *tbl);
92 struct nfs4_slot_table *tbl);
93 93
94static inline bool nfs4_session_draining(struct nfs4_session *session) 94static inline bool nfs4_slot_tbl_draining(struct nfs4_slot_table *tbl)
95{ 95{
96 return !!test_bit(NFS4_SESSION_DRAINING, &session->session_state); 96 return !!test_bit(NFS4_SLOT_TBL_DRAINING, &tbl->slot_tbl_state);
97} 97}
98 98
99bool nfs41_wake_and_assign_slot(struct nfs4_slot_table *tbl, 99bool nfs41_wake_and_assign_slot(struct nfs4_slot_table *tbl,
@@ -119,7 +119,7 @@ static inline int nfs4_has_persistent_session(const struct nfs_client *clp)
119 119
120#else /* defined(CONFIG_NFS_V4_1) */ 120#else /* defined(CONFIG_NFS_V4_1) */
121 121
122static inline int nfs4_init_session(struct nfs_server *server) 122static inline int nfs4_init_session(struct nfs_client *clp)
123{ 123{
124 return 0; 124 return 0;
125} 125}
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index 300d17d85c0e..b0e42d7a19a1 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -228,38 +228,37 @@ static int nfs41_setup_state_renewal(struct nfs_client *clp)
228 return status; 228 return status;
229} 229}
230 230
231/* 231static void nfs4_end_drain_slot_table(struct nfs4_slot_table *tbl)
232 * Back channel returns NFS4ERR_DELAY for new requests when
233 * NFS4_SESSION_DRAINING is set so there is no work to be done when draining
234 * is ended.
235 */
236static void nfs4_end_drain_session(struct nfs_client *clp)
237{ 232{
238 struct nfs4_session *ses = clp->cl_session; 233 if (test_and_clear_bit(NFS4_SLOT_TBL_DRAINING, &tbl->slot_tbl_state)) {
239 struct nfs4_slot_table *tbl;
240
241 if (ses == NULL)
242 return;
243 tbl = &ses->fc_slot_table;
244 if (test_and_clear_bit(NFS4_SESSION_DRAINING, &ses->session_state)) {
245 spin_lock(&tbl->slot_tbl_lock); 234 spin_lock(&tbl->slot_tbl_lock);
246 nfs41_wake_slot_table(tbl); 235 nfs41_wake_slot_table(tbl);
247 spin_unlock(&tbl->slot_tbl_lock); 236 spin_unlock(&tbl->slot_tbl_lock);
248 } 237 }
249} 238}
250 239
240static void nfs4_end_drain_session(struct nfs_client *clp)
241{
242 struct nfs4_session *ses = clp->cl_session;
243
244 if (ses != NULL) {
245 nfs4_end_drain_slot_table(&ses->bc_slot_table);
246 nfs4_end_drain_slot_table(&ses->fc_slot_table);
247 }
248}
249
251/* 250/*
252 * Signal state manager thread if session fore channel is drained 251 * Signal state manager thread if session fore channel is drained
253 */ 252 */
254void nfs4_session_drain_complete(struct nfs4_session *session, 253void nfs4_slot_tbl_drain_complete(struct nfs4_slot_table *tbl)
255 struct nfs4_slot_table *tbl)
256{ 254{
257 if (nfs4_session_draining(session)) 255 if (nfs4_slot_tbl_draining(tbl))
258 complete(&tbl->complete); 256 complete(&tbl->complete);
259} 257}
260 258
261static int nfs4_wait_on_slot_tbl(struct nfs4_slot_table *tbl) 259static int nfs4_drain_slot_tbl(struct nfs4_slot_table *tbl)
262{ 260{
261 set_bit(NFS4_SLOT_TBL_DRAINING, &tbl->slot_tbl_state);
263 spin_lock(&tbl->slot_tbl_lock); 262 spin_lock(&tbl->slot_tbl_lock);
264 if (tbl->highest_used_slotid != NFS4_NO_SLOT) { 263 if (tbl->highest_used_slotid != NFS4_NO_SLOT) {
265 INIT_COMPLETION(tbl->complete); 264 INIT_COMPLETION(tbl->complete);
@@ -275,13 +274,12 @@ static int nfs4_begin_drain_session(struct nfs_client *clp)
275 struct nfs4_session *ses = clp->cl_session; 274 struct nfs4_session *ses = clp->cl_session;
276 int ret = 0; 275 int ret = 0;
277 276
278 set_bit(NFS4_SESSION_DRAINING, &ses->session_state);
279 /* back channel */ 277 /* back channel */
280 ret = nfs4_wait_on_slot_tbl(&ses->bc_slot_table); 278 ret = nfs4_drain_slot_tbl(&ses->bc_slot_table);
281 if (ret) 279 if (ret)
282 return ret; 280 return ret;
283 /* fore channel */ 281 /* fore channel */
284 return nfs4_wait_on_slot_tbl(&ses->fc_slot_table); 282 return nfs4_drain_slot_tbl(&ses->fc_slot_table);
285} 283}
286 284
287static void nfs41_finish_session_reset(struct nfs_client *clp) 285static void nfs41_finish_session_reset(struct nfs_client *clp)
@@ -1564,11 +1562,12 @@ static void nfs4_state_start_reclaim_reboot(struct nfs_client *clp)
1564} 1562}
1565 1563
1566static void nfs4_reclaim_complete(struct nfs_client *clp, 1564static void nfs4_reclaim_complete(struct nfs_client *clp,
1567 const struct nfs4_state_recovery_ops *ops) 1565 const struct nfs4_state_recovery_ops *ops,
1566 struct rpc_cred *cred)
1568{ 1567{
1569 /* Notify the server we're done reclaiming our state */ 1568 /* Notify the server we're done reclaiming our state */
1570 if (ops->reclaim_complete) 1569 if (ops->reclaim_complete)
1571 (void)ops->reclaim_complete(clp); 1570 (void)ops->reclaim_complete(clp, cred);
1572} 1571}
1573 1572
1574static void nfs4_clear_reclaim_server(struct nfs_server *server) 1573static void nfs4_clear_reclaim_server(struct nfs_server *server)
@@ -1613,9 +1612,15 @@ static int nfs4_state_clear_reclaim_reboot(struct nfs_client *clp)
1613 1612
1614static void nfs4_state_end_reclaim_reboot(struct nfs_client *clp) 1613static void nfs4_state_end_reclaim_reboot(struct nfs_client *clp)
1615{ 1614{
1615 const struct nfs4_state_recovery_ops *ops;
1616 struct rpc_cred *cred;
1617
1616 if (!nfs4_state_clear_reclaim_reboot(clp)) 1618 if (!nfs4_state_clear_reclaim_reboot(clp))
1617 return; 1619 return;
1618 nfs4_reclaim_complete(clp, clp->cl_mvops->reboot_recovery_ops); 1620 ops = clp->cl_mvops->reboot_recovery_ops;
1621 cred = ops->get_clid_cred(clp);
1622 nfs4_reclaim_complete(clp, ops, cred);
1623 put_rpccred(cred);
1619} 1624}
1620 1625
1621static void nfs_delegation_clear_all(struct nfs_client *clp) 1626static void nfs_delegation_clear_all(struct nfs_client *clp)
diff --git a/fs/nfs/nfs4super.c b/fs/nfs/nfs4super.c
index a5e1a3026d48..5dbe2d269210 100644
--- a/fs/nfs/nfs4super.c
+++ b/fs/nfs/nfs4super.c
@@ -9,6 +9,7 @@
9#include "delegation.h" 9#include "delegation.h"
10#include "internal.h" 10#include "internal.h"
11#include "nfs4_fs.h" 11#include "nfs4_fs.h"
12#include "dns_resolve.h"
12#include "pnfs.h" 13#include "pnfs.h"
13#include "nfs.h" 14#include "nfs.h"
14 15
@@ -331,18 +332,24 @@ static int __init init_nfs_v4(void)
331{ 332{
332 int err; 333 int err;
333 334
334 err = nfs_idmap_init(); 335 err = nfs_dns_resolver_init();
335 if (err) 336 if (err)
336 goto out; 337 goto out;
337 338
338 err = nfs4_register_sysctl(); 339 err = nfs_idmap_init();
339 if (err) 340 if (err)
340 goto out1; 341 goto out1;
341 342
343 err = nfs4_register_sysctl();
344 if (err)
345 goto out2;
346
342 register_nfs_version(&nfs_v4); 347 register_nfs_version(&nfs_v4);
343 return 0; 348 return 0;
344out1: 349out2:
345 nfs_idmap_quit(); 350 nfs_idmap_quit();
351out1:
352 nfs_dns_resolver_destroy();
346out: 353out:
347 return err; 354 return err;
348} 355}
@@ -352,6 +359,7 @@ static void __exit exit_nfs_v4(void)
352 unregister_nfs_version(&nfs_v4); 359 unregister_nfs_version(&nfs_v4);
353 nfs4_unregister_sysctl(); 360 nfs4_unregister_sysctl();
354 nfs_idmap_quit(); 361 nfs_idmap_quit();
362 nfs_dns_resolver_destroy();
355} 363}
356 364
357MODULE_LICENSE("GPL"); 365MODULE_LICENSE("GPL");
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 2a3f77e14db6..0abfb8466e79 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -867,6 +867,12 @@ const u32 nfs41_maxread_overhead = ((RPC_MAX_HEADER_WITH_AUTH +
867 decode_sequence_maxsz + 867 decode_sequence_maxsz +
868 decode_putfh_maxsz) * 868 decode_putfh_maxsz) *
869 XDR_UNIT); 869 XDR_UNIT);
870
871const u32 nfs41_maxgetdevinfo_overhead = ((RPC_MAX_REPHEADER_WITH_AUTH +
872 compound_decode_hdr_maxsz +
873 decode_sequence_maxsz) *
874 XDR_UNIT);
875EXPORT_SYMBOL_GPL(nfs41_maxgetdevinfo_overhead);
870#endif /* CONFIG_NFS_V4_1 */ 876#endif /* CONFIG_NFS_V4_1 */
871 877
872static const umode_t nfs_type2fmt[] = { 878static const umode_t nfs_type2fmt[] = {
@@ -1924,7 +1930,7 @@ encode_getdeviceinfo(struct xdr_stream *xdr,
1924 p = xdr_encode_opaque_fixed(p, args->pdev->dev_id.data, 1930 p = xdr_encode_opaque_fixed(p, args->pdev->dev_id.data,
1925 NFS4_DEVICEID4_SIZE); 1931 NFS4_DEVICEID4_SIZE);
1926 *p++ = cpu_to_be32(args->pdev->layout_type); 1932 *p++ = cpu_to_be32(args->pdev->layout_type);
1927 *p++ = cpu_to_be32(args->pdev->pglen); /* gdia_maxcount */ 1933 *p++ = cpu_to_be32(args->pdev->maxcount); /* gdia_maxcount */
1928 *p++ = cpu_to_be32(0); /* bitmap length 0 */ 1934 *p++ = cpu_to_be32(0); /* bitmap length 0 */
1929} 1935}
1930 1936
diff --git a/fs/nfs/objlayout/objlayout.c b/fs/nfs/objlayout/objlayout.c
index a9ebd817278b..e4f9cbfec67b 100644
--- a/fs/nfs/objlayout/objlayout.c
+++ b/fs/nfs/objlayout/objlayout.c
@@ -613,8 +613,10 @@ int objlayout_get_deviceinfo(struct pnfs_layout_hdr *pnfslay,
613 pd.pgbase = 0; 613 pd.pgbase = 0;
614 pd.pglen = PAGE_SIZE; 614 pd.pglen = PAGE_SIZE;
615 pd.mincount = 0; 615 pd.mincount = 0;
616 pd.maxcount = PAGE_SIZE;
616 617
617 err = nfs4_proc_getdeviceinfo(NFS_SERVER(pnfslay->plh_inode), &pd); 618 err = nfs4_proc_getdeviceinfo(NFS_SERVER(pnfslay->plh_inode), &pd,
619 pnfslay->plh_lc_cred);
618 dprintk("%s nfs_getdeviceinfo returned %d\n", __func__, err); 620 dprintk("%s nfs_getdeviceinfo returned %d\n", __func__, err);
619 if (err) 621 if (err)
620 goto err_out; 622 goto err_out;
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index c5bd758e5637..3a3a79d6bf15 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -360,7 +360,7 @@ pnfs_put_lseg(struct pnfs_layout_segment *lseg)
360} 360}
361EXPORT_SYMBOL_GPL(pnfs_put_lseg); 361EXPORT_SYMBOL_GPL(pnfs_put_lseg);
362 362
363static inline u64 363static u64
364end_offset(u64 start, u64 len) 364end_offset(u64 start, u64 len)
365{ 365{
366 u64 end; 366 u64 end;
@@ -376,9 +376,9 @@ end_offset(u64 start, u64 len)
376 * start2 end2 376 * start2 end2
377 * [----------------) 377 * [----------------)
378 */ 378 */
379static inline int 379static bool
380lo_seg_contained(struct pnfs_layout_range *l1, 380pnfs_lseg_range_contained(const struct pnfs_layout_range *l1,
381 struct pnfs_layout_range *l2) 381 const struct pnfs_layout_range *l2)
382{ 382{
383 u64 start1 = l1->offset; 383 u64 start1 = l1->offset;
384 u64 end1 = end_offset(start1, l1->length); 384 u64 end1 = end_offset(start1, l1->length);
@@ -395,9 +395,9 @@ lo_seg_contained(struct pnfs_layout_range *l1,
395 * start2 end2 395 * start2 end2
396 * [----------------) 396 * [----------------)
397 */ 397 */
398static inline int 398static bool
399lo_seg_intersecting(struct pnfs_layout_range *l1, 399pnfs_lseg_range_intersecting(const struct pnfs_layout_range *l1,
400 struct pnfs_layout_range *l2) 400 const struct pnfs_layout_range *l2)
401{ 401{
402 u64 start1 = l1->offset; 402 u64 start1 = l1->offset;
403 u64 end1 = end_offset(start1, l1->length); 403 u64 end1 = end_offset(start1, l1->length);
@@ -409,12 +409,12 @@ lo_seg_intersecting(struct pnfs_layout_range *l1,
409} 409}
410 410
411static bool 411static bool
412should_free_lseg(struct pnfs_layout_range *lseg_range, 412should_free_lseg(const struct pnfs_layout_range *lseg_range,
413 struct pnfs_layout_range *recall_range) 413 const struct pnfs_layout_range *recall_range)
414{ 414{
415 return (recall_range->iomode == IOMODE_ANY || 415 return (recall_range->iomode == IOMODE_ANY ||
416 lseg_range->iomode == recall_range->iomode) && 416 lseg_range->iomode == recall_range->iomode) &&
417 lo_seg_intersecting(lseg_range, recall_range); 417 pnfs_lseg_range_intersecting(lseg_range, recall_range);
418} 418}
419 419
420static bool pnfs_lseg_dec_and_remove_zero(struct pnfs_layout_segment *lseg, 420static bool pnfs_lseg_dec_and_remove_zero(struct pnfs_layout_segment *lseg,
@@ -766,6 +766,7 @@ send_layoutget(struct pnfs_layout_hdr *lo,
766 lgp->args.inode = ino; 766 lgp->args.inode = ino;
767 lgp->args.ctx = get_nfs_open_context(ctx); 767 lgp->args.ctx = get_nfs_open_context(ctx);
768 lgp->gfp_flags = gfp_flags; 768 lgp->gfp_flags = gfp_flags;
769 lgp->cred = lo->plh_lc_cred;
769 770
770 /* Synchronously retrieve layout information from server and 771 /* Synchronously retrieve layout information from server and
771 * store in lseg. 772 * store in lseg.
@@ -860,6 +861,7 @@ _pnfs_return_layout(struct inode *ino)
860 lrp->args.inode = ino; 861 lrp->args.inode = ino;
861 lrp->args.layout = lo; 862 lrp->args.layout = lo;
862 lrp->clp = NFS_SERVER(ino)->nfs_client; 863 lrp->clp = NFS_SERVER(ino)->nfs_client;
864 lrp->cred = lo->plh_lc_cred;
863 865
864 status = nfs4_proc_layoutreturn(lrp); 866 status = nfs4_proc_layoutreturn(lrp);
865out: 867out:
@@ -984,8 +986,8 @@ out:
984 * are seen first. 986 * are seen first.
985 */ 987 */
986static s64 988static s64
987cmp_layout(struct pnfs_layout_range *l1, 989pnfs_lseg_range_cmp(const struct pnfs_layout_range *l1,
988 struct pnfs_layout_range *l2) 990 const struct pnfs_layout_range *l2)
989{ 991{
990 s64 d; 992 s64 d;
991 993
@@ -1012,7 +1014,7 @@ pnfs_layout_insert_lseg(struct pnfs_layout_hdr *lo,
1012 dprintk("%s:Begin\n", __func__); 1014 dprintk("%s:Begin\n", __func__);
1013 1015
1014 list_for_each_entry(lp, &lo->plh_segs, pls_list) { 1016 list_for_each_entry(lp, &lo->plh_segs, pls_list) {
1015 if (cmp_layout(&lseg->pls_range, &lp->pls_range) > 0) 1017 if (pnfs_lseg_range_cmp(&lseg->pls_range, &lp->pls_range) > 0)
1016 continue; 1018 continue;
1017 list_add_tail(&lseg->pls_list, &lp->pls_list); 1019 list_add_tail(&lseg->pls_list, &lp->pls_list);
1018 dprintk("%s: inserted lseg %p " 1020 dprintk("%s: inserted lseg %p "
@@ -1050,7 +1052,7 @@ alloc_init_layout_hdr(struct inode *ino,
1050 INIT_LIST_HEAD(&lo->plh_segs); 1052 INIT_LIST_HEAD(&lo->plh_segs);
1051 INIT_LIST_HEAD(&lo->plh_bulk_destroy); 1053 INIT_LIST_HEAD(&lo->plh_bulk_destroy);
1052 lo->plh_inode = ino; 1054 lo->plh_inode = ino;
1053 lo->plh_lc_cred = get_rpccred(ctx->state->owner->so_cred); 1055 lo->plh_lc_cred = get_rpccred(ctx->cred);
1054 return lo; 1056 return lo;
1055} 1057}
1056 1058
@@ -1091,21 +1093,21 @@ out_existing:
1091 * READ READ true 1093 * READ READ true
1092 * READ RW true 1094 * READ RW true
1093 */ 1095 */
1094static int 1096static bool
1095is_matching_lseg(struct pnfs_layout_range *ls_range, 1097pnfs_lseg_range_match(const struct pnfs_layout_range *ls_range,
1096 struct pnfs_layout_range *range) 1098 const struct pnfs_layout_range *range)
1097{ 1099{
1098 struct pnfs_layout_range range1; 1100 struct pnfs_layout_range range1;
1099 1101
1100 if ((range->iomode == IOMODE_RW && 1102 if ((range->iomode == IOMODE_RW &&
1101 ls_range->iomode != IOMODE_RW) || 1103 ls_range->iomode != IOMODE_RW) ||
1102 !lo_seg_intersecting(ls_range, range)) 1104 !pnfs_lseg_range_intersecting(ls_range, range))
1103 return 0; 1105 return 0;
1104 1106
1105 /* range1 covers only the first byte in the range */ 1107 /* range1 covers only the first byte in the range */
1106 range1 = *range; 1108 range1 = *range;
1107 range1.length = 1; 1109 range1.length = 1;
1108 return lo_seg_contained(ls_range, &range1); 1110 return pnfs_lseg_range_contained(ls_range, &range1);
1109} 1111}
1110 1112
1111/* 1113/*
@@ -1121,7 +1123,7 @@ pnfs_find_lseg(struct pnfs_layout_hdr *lo,
1121 1123
1122 list_for_each_entry(lseg, &lo->plh_segs, pls_list) { 1124 list_for_each_entry(lseg, &lo->plh_segs, pls_list) {
1123 if (test_bit(NFS_LSEG_VALID, &lseg->pls_flags) && 1125 if (test_bit(NFS_LSEG_VALID, &lseg->pls_flags) &&
1124 is_matching_lseg(&lseg->pls_range, range)) { 1126 pnfs_lseg_range_match(&lseg->pls_range, range)) {
1125 ret = pnfs_get_lseg(lseg); 1127 ret = pnfs_get_lseg(lseg);
1126 break; 1128 break;
1127 } 1129 }
diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h
index f5f8a470a647..a4f41810a7f4 100644
--- a/fs/nfs/pnfs.h
+++ b/fs/nfs/pnfs.h
@@ -149,9 +149,10 @@ struct pnfs_device {
149 struct nfs4_deviceid dev_id; 149 struct nfs4_deviceid dev_id;
150 unsigned int layout_type; 150 unsigned int layout_type;
151 unsigned int mincount; 151 unsigned int mincount;
152 unsigned int maxcount; /* gdia_maxcount */
152 struct page **pages; 153 struct page **pages;
153 unsigned int pgbase; 154 unsigned int pgbase;
154 unsigned int pglen; 155 unsigned int pglen; /* reply buffer length */
155}; 156};
156 157
157#define NFS4_PNFS_GETDEVLIST_MAXNUM 16 158#define NFS4_PNFS_GETDEVLIST_MAXNUM 16
@@ -170,7 +171,8 @@ extern int nfs4_proc_getdevicelist(struct nfs_server *server,
170 const struct nfs_fh *fh, 171 const struct nfs_fh *fh,
171 struct pnfs_devicelist *devlist); 172 struct pnfs_devicelist *devlist);
172extern int nfs4_proc_getdeviceinfo(struct nfs_server *server, 173extern int nfs4_proc_getdeviceinfo(struct nfs_server *server,
173 struct pnfs_device *dev); 174 struct pnfs_device *dev,
175 struct rpc_cred *cred);
174extern struct pnfs_layout_segment* nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags); 176extern struct pnfs_layout_segment* nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags);
175extern int nfs4_proc_layoutreturn(struct nfs4_layoutreturn *lrp); 177extern int nfs4_proc_layoutreturn(struct nfs4_layoutreturn *lrp);
176 178
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 76e1ee5d03ed..71fdc0dfa0d2 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -1614,29 +1614,13 @@ out_security_failure:
1614} 1614}
1615 1615
1616/* 1616/*
1617 * Select a security flavor for this mount. The selected flavor 1617 * Ensure that the specified authtype in args->auth_flavors[0] is supported by
1618 * is planted in args->auth_flavors[0]. 1618 * the server. Returns 0 if it's ok, and -EACCES if not.
1619 *
1620 * Returns 0 on success, -EACCES on failure.
1621 */ 1619 */
1622static int nfs_select_flavor(struct nfs_parsed_mount_data *args, 1620static int nfs_verify_authflavor(struct nfs_parsed_mount_data *args,
1623 struct nfs_mount_request *request) 1621 rpc_authflavor_t *server_authlist, unsigned int count)
1624{ 1622{
1625 unsigned int i, count = *(request->auth_flav_len); 1623 unsigned int i;
1626 rpc_authflavor_t flavor;
1627
1628 /*
1629 * The NFSv2 MNT operation does not return a flavor list.
1630 */
1631 if (args->mount_server.version != NFS_MNT3_VERSION)
1632 goto out_default;
1633
1634 /*
1635 * Certain releases of Linux's mountd return an empty
1636 * flavor list in some cases.
1637 */
1638 if (count == 0)
1639 goto out_default;
1640 1624
1641 /* 1625 /*
1642 * If the sec= mount option is used, the specified flavor or AUTH_NULL 1626 * If the sec= mount option is used, the specified flavor or AUTH_NULL
@@ -1646,60 +1630,19 @@ static int nfs_select_flavor(struct nfs_parsed_mount_data *args,
1646 * means that the server will ignore the rpc creds, so any flavor 1630 * means that the server will ignore the rpc creds, so any flavor
1647 * can be used. 1631 * can be used.
1648 */ 1632 */
1649 if (args->auth_flavors[0] != RPC_AUTH_MAXFLAVOR) {
1650 for (i = 0; i < count; i++) {
1651 if (args->auth_flavors[0] == request->auth_flavs[i] ||
1652 request->auth_flavs[i] == RPC_AUTH_NULL)
1653 goto out;
1654 }
1655 dfprintk(MOUNT, "NFS: auth flavor %d not supported by server\n",
1656 args->auth_flavors[0]);
1657 goto out_err;
1658 }
1659
1660 /*
1661 * RFC 2623, section 2.7 suggests we SHOULD prefer the
1662 * flavor listed first. However, some servers list
1663 * AUTH_NULL first. Avoid ever choosing AUTH_NULL.
1664 */
1665 for (i = 0; i < count; i++) {
1666 struct rpcsec_gss_info info;
1667
1668 flavor = request->auth_flavs[i];
1669 switch (flavor) {
1670 case RPC_AUTH_UNIX:
1671 goto out_set;
1672 case RPC_AUTH_NULL:
1673 continue;
1674 default:
1675 if (rpcauth_get_gssinfo(flavor, &info) == 0)
1676 goto out_set;
1677 }
1678 }
1679
1680 /*
1681 * As a last chance, see if the server list contains AUTH_NULL -
1682 * if it does, use the default flavor.
1683 */
1684 for (i = 0; i < count; i++) { 1633 for (i = 0; i < count; i++) {
1685 if (request->auth_flavs[i] == RPC_AUTH_NULL) 1634 if (args->auth_flavors[0] == server_authlist[i] ||
1686 goto out_default; 1635 server_authlist[i] == RPC_AUTH_NULL)
1636 goto out;
1687 } 1637 }
1688 1638
1689 dfprintk(MOUNT, "NFS: no auth flavors in common with server\n"); 1639 dfprintk(MOUNT, "NFS: auth flavor %u not supported by server\n",
1690 goto out_err; 1640 args->auth_flavors[0]);
1641 return -EACCES;
1691 1642
1692out_default:
1693 /* use default if flavor not already set */
1694 flavor = (args->auth_flavors[0] == RPC_AUTH_MAXFLAVOR) ?
1695 RPC_AUTH_UNIX : args->auth_flavors[0];
1696out_set:
1697 args->auth_flavors[0] = flavor;
1698out: 1643out:
1699 dfprintk(MOUNT, "NFS: using auth flavor %d\n", args->auth_flavors[0]); 1644 dfprintk(MOUNT, "NFS: using auth flavor %u\n", args->auth_flavors[0]);
1700 return 0; 1645 return 0;
1701out_err:
1702 return -EACCES;
1703} 1646}
1704 1647
1705/* 1648/*
@@ -1707,10 +1650,10 @@ out_err:
1707 * corresponding to the provided path. 1650 * corresponding to the provided path.
1708 */ 1651 */
1709static int nfs_request_mount(struct nfs_parsed_mount_data *args, 1652static int nfs_request_mount(struct nfs_parsed_mount_data *args,
1710 struct nfs_fh *root_fh) 1653 struct nfs_fh *root_fh,
1654 rpc_authflavor_t *server_authlist,
1655 unsigned int *server_authlist_len)
1711{ 1656{
1712 rpc_authflavor_t server_authlist[NFS_MAX_SECFLAVORS];
1713 unsigned int server_authlist_len = ARRAY_SIZE(server_authlist);
1714 struct nfs_mount_request request = { 1657 struct nfs_mount_request request = {
1715 .sap = (struct sockaddr *) 1658 .sap = (struct sockaddr *)
1716 &args->mount_server.address, 1659 &args->mount_server.address,
@@ -1718,7 +1661,7 @@ static int nfs_request_mount(struct nfs_parsed_mount_data *args,
1718 .protocol = args->mount_server.protocol, 1661 .protocol = args->mount_server.protocol,
1719 .fh = root_fh, 1662 .fh = root_fh,
1720 .noresvport = args->flags & NFS_MOUNT_NORESVPORT, 1663 .noresvport = args->flags & NFS_MOUNT_NORESVPORT,
1721 .auth_flav_len = &server_authlist_len, 1664 .auth_flav_len = server_authlist_len,
1722 .auth_flavs = server_authlist, 1665 .auth_flavs = server_authlist,
1723 .net = args->net, 1666 .net = args->net,
1724 }; 1667 };
@@ -1762,24 +1705,92 @@ static int nfs_request_mount(struct nfs_parsed_mount_data *args,
1762 return status; 1705 return status;
1763 } 1706 }
1764 1707
1765 return nfs_select_flavor(args, &request); 1708 return 0;
1766} 1709}
1767 1710
1768struct dentry *nfs_try_mount(int flags, const char *dev_name, 1711static struct nfs_server *nfs_try_mount_request(struct nfs_mount_info *mount_info,
1769 struct nfs_mount_info *mount_info, 1712 struct nfs_subversion *nfs_mod)
1770 struct nfs_subversion *nfs_mod)
1771{ 1713{
1772 int status; 1714 int status;
1773 struct nfs_server *server; 1715 unsigned int i;
1716 bool tried_auth_unix = false;
1717 bool auth_null_in_list = false;
1718 struct nfs_server *server = ERR_PTR(-EACCES);
1719 struct nfs_parsed_mount_data *args = mount_info->parsed;
1720 rpc_authflavor_t authlist[NFS_MAX_SECFLAVORS];
1721 unsigned int authlist_len = ARRAY_SIZE(authlist);
1722
1723 status = nfs_request_mount(args, mount_info->mntfh, authlist,
1724 &authlist_len);
1725 if (status)
1726 return ERR_PTR(status);
1774 1727
1775 if (mount_info->parsed->need_mount) { 1728 /*
1776 status = nfs_request_mount(mount_info->parsed, mount_info->mntfh); 1729 * Was a sec= authflavor specified in the options? First, verify
1730 * whether the server supports it, and then just try to use it if so.
1731 */
1732 if (args->auth_flavors[0] != RPC_AUTH_MAXFLAVOR) {
1733 status = nfs_verify_authflavor(args, authlist, authlist_len);
1734 dfprintk(MOUNT, "NFS: using auth flavor %u\n", args->auth_flavors[0]);
1777 if (status) 1735 if (status)
1778 return ERR_PTR(status); 1736 return ERR_PTR(status);
1737 return nfs_mod->rpc_ops->create_server(mount_info, nfs_mod);
1779 } 1738 }
1780 1739
1781 /* Get a volume representation */ 1740 /*
1782 server = nfs_mod->rpc_ops->create_server(mount_info, nfs_mod); 1741 * No sec= option was provided. RFC 2623, section 2.7 suggests we
1742 * SHOULD prefer the flavor listed first. However, some servers list
1743 * AUTH_NULL first. Avoid ever choosing AUTH_NULL.
1744 */
1745 for (i = 0; i < authlist_len; ++i) {
1746 rpc_authflavor_t flavor;
1747 struct rpcsec_gss_info info;
1748
1749 flavor = authlist[i];
1750 switch (flavor) {
1751 case RPC_AUTH_UNIX:
1752 tried_auth_unix = true;
1753 break;
1754 case RPC_AUTH_NULL:
1755 auth_null_in_list = true;
1756 continue;
1757 default:
1758 if (rpcauth_get_gssinfo(flavor, &info) != 0)
1759 continue;
1760 /* Fallthrough */
1761 }
1762 dfprintk(MOUNT, "NFS: attempting to use auth flavor %u\n", flavor);
1763 args->auth_flavors[0] = flavor;
1764 server = nfs_mod->rpc_ops->create_server(mount_info, nfs_mod);
1765 if (!IS_ERR(server))
1766 return server;
1767 }
1768
1769 /*
1770 * Nothing we tried so far worked. At this point, give up if we've
1771 * already tried AUTH_UNIX or if the server's list doesn't contain
1772 * AUTH_NULL
1773 */
1774 if (tried_auth_unix || !auth_null_in_list)
1775 return server;
1776
1777 /* Last chance! Try AUTH_UNIX */
1778 dfprintk(MOUNT, "NFS: attempting to use auth flavor %u\n", RPC_AUTH_UNIX);
1779 args->auth_flavors[0] = RPC_AUTH_UNIX;
1780 return nfs_mod->rpc_ops->create_server(mount_info, nfs_mod);
1781}
1782
1783struct dentry *nfs_try_mount(int flags, const char *dev_name,
1784 struct nfs_mount_info *mount_info,
1785 struct nfs_subversion *nfs_mod)
1786{
1787 struct nfs_server *server;
1788
1789 if (mount_info->parsed->need_mount)
1790 server = nfs_try_mount_request(mount_info, nfs_mod);
1791 else
1792 server = nfs_mod->rpc_ops->create_server(mount_info, nfs_mod);
1793
1783 if (IS_ERR(server)) 1794 if (IS_ERR(server))
1784 return ERR_CAST(server); 1795 return ERR_CAST(server);
1785 1796
@@ -1948,6 +1959,7 @@ static int nfs23_validate_mount_data(void *options,
1948 args->namlen = data->namlen; 1959 args->namlen = data->namlen;
1949 args->bsize = data->bsize; 1960 args->bsize = data->bsize;
1950 1961
1962 args->auth_flavors[0] = RPC_AUTH_UNIX;
1951 if (data->flags & NFS_MOUNT_SECFLAVOUR) 1963 if (data->flags & NFS_MOUNT_SECFLAVOUR)
1952 args->auth_flavors[0] = data->pseudoflavor; 1964 args->auth_flavors[0] = data->pseudoflavor;
1953 if (!args->nfs_server.hostname) 1965 if (!args->nfs_server.hostname)
@@ -2657,6 +2669,7 @@ static int nfs4_validate_mount_data(void *options,
2657 goto out_no_address; 2669 goto out_no_address;
2658 args->nfs_server.port = ntohs(((struct sockaddr_in *)sap)->sin_port); 2670 args->nfs_server.port = ntohs(((struct sockaddr_in *)sap)->sin_port);
2659 2671
2672 args->auth_flavors[0] = RPC_AUTH_UNIX;
2660 if (data->auth_flavourlen) { 2673 if (data->auth_flavourlen) {
2661 if (data->auth_flavourlen > 1) 2674 if (data->auth_flavourlen > 1)
2662 goto out_inval_auth; 2675 goto out_inval_auth;
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
index d4b003d9e78d..0b176297aaf6 100644
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -359,6 +359,7 @@ extern struct nfs_open_context *get_nfs_open_context(struct nfs_open_context *ct
359extern void put_nfs_open_context(struct nfs_open_context *ctx); 359extern void put_nfs_open_context(struct nfs_open_context *ctx);
360extern struct nfs_open_context *nfs_find_open_context(struct inode *inode, struct rpc_cred *cred, fmode_t mode); 360extern struct nfs_open_context *nfs_find_open_context(struct inode *inode, struct rpc_cred *cred, fmode_t mode);
361extern struct nfs_open_context *alloc_nfs_open_context(struct dentry *dentry, fmode_t f_mode); 361extern struct nfs_open_context *alloc_nfs_open_context(struct dentry *dentry, fmode_t f_mode);
362extern void nfs_inode_attach_open_context(struct nfs_open_context *ctx);
362extern void nfs_file_set_open_context(struct file *filp, struct nfs_open_context *ctx); 363extern void nfs_file_set_open_context(struct file *filp, struct nfs_open_context *ctx);
363extern struct nfs_lock_context *nfs_get_lock_context(struct nfs_open_context *ctx); 364extern struct nfs_lock_context *nfs_get_lock_context(struct nfs_open_context *ctx);
364extern void nfs_put_lock_context(struct nfs_lock_context *l_ctx); 365extern void nfs_put_lock_context(struct nfs_lock_context *l_ctx);
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index ed31ba7a6f9e..8651574a305b 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -248,6 +248,7 @@ struct nfs4_layoutget_res {
248struct nfs4_layoutget { 248struct nfs4_layoutget {
249 struct nfs4_layoutget_args args; 249 struct nfs4_layoutget_args args;
250 struct nfs4_layoutget_res res; 250 struct nfs4_layoutget_res res;
251 struct rpc_cred *cred;
251 gfp_t gfp_flags; 252 gfp_t gfp_flags;
252}; 253};
253 254
diff --git a/include/linux/sunrpc/sched.h b/include/linux/sunrpc/sched.h
index 84ca436b76c2..6d870353674a 100644
--- a/include/linux/sunrpc/sched.h
+++ b/include/linux/sunrpc/sched.h
@@ -88,15 +88,6 @@ struct rpc_task {
88 tk_rebind_retry : 2; 88 tk_rebind_retry : 2;
89}; 89};
90 90
91/* support walking a list of tasks on a wait queue */
92#define task_for_each(task, pos, head) \
93 list_for_each(pos, head) \
94 if ((task=list_entry(pos, struct rpc_task, u.tk_wait.list)),1)
95
96#define task_for_first(task, head) \
97 if (!list_empty(head) && \
98 ((task=list_entry((head)->next, struct rpc_task, u.tk_wait.list)),1))
99
100typedef void (*rpc_action)(struct rpc_task *); 91typedef void (*rpc_action)(struct rpc_task *);
101 92
102struct rpc_call_ops { 93struct rpc_call_ops {
@@ -238,7 +229,6 @@ struct rpc_task *rpc_wake_up_first(struct rpc_wait_queue *,
238 bool (*)(struct rpc_task *, void *), 229 bool (*)(struct rpc_task *, void *),
239 void *); 230 void *);
240void rpc_wake_up_status(struct rpc_wait_queue *, int); 231void rpc_wake_up_status(struct rpc_wait_queue *, int);
241int rpc_queue_empty(struct rpc_wait_queue *);
242void rpc_delay(struct rpc_task *, unsigned long); 232void rpc_delay(struct rpc_task *, unsigned long);
243void * rpc_malloc(struct rpc_task *, size_t); 233void * rpc_malloc(struct rpc_task *, size_t);
244void rpc_free(void *); 234void rpc_free(void *);
@@ -259,16 +249,6 @@ static inline int rpc_wait_for_completion_task(struct rpc_task *task)
259 return __rpc_wait_for_completion_task(task, NULL); 249 return __rpc_wait_for_completion_task(task, NULL);
260} 250}
261 251
262static inline void rpc_task_set_priority(struct rpc_task *task, unsigned char prio)
263{
264 task->tk_priority = prio - RPC_PRIORITY_LOW;
265}
266
267static inline int rpc_task_has_priority(struct rpc_task *task, unsigned char prio)
268{
269 return (task->tk_priority + RPC_PRIORITY_LOW == prio);
270}
271
272#if defined(RPC_DEBUG) || defined (RPC_TRACEPOINTS) 252#if defined(RPC_DEBUG) || defined (RPC_TRACEPOINTS)
273static inline const char * rpc_qname(const struct rpc_wait_queue *q) 253static inline const char * rpc_qname(const struct rpc_wait_queue *q)
274{ 254{
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
index 7da6b457f66a..fc2f78d6a9b4 100644
--- a/net/sunrpc/auth_gss/auth_gss.c
+++ b/net/sunrpc/auth_gss/auth_gss.c
@@ -52,6 +52,8 @@
52#include <linux/sunrpc/gss_api.h> 52#include <linux/sunrpc/gss_api.h>
53#include <asm/uaccess.h> 53#include <asm/uaccess.h>
54 54
55#include "../netns.h"
56
55static const struct rpc_authops authgss_ops; 57static const struct rpc_authops authgss_ops;
56 58
57static const struct rpc_credops gss_credops; 59static const struct rpc_credops gss_credops;
@@ -85,8 +87,6 @@ struct gss_auth {
85}; 87};
86 88
87/* pipe_version >= 0 if and only if someone has a pipe open. */ 89/* pipe_version >= 0 if and only if someone has a pipe open. */
88static int pipe_version = -1;
89static atomic_t pipe_users = ATOMIC_INIT(0);
90static DEFINE_SPINLOCK(pipe_version_lock); 90static DEFINE_SPINLOCK(pipe_version_lock);
91static struct rpc_wait_queue pipe_version_rpc_waitqueue; 91static struct rpc_wait_queue pipe_version_rpc_waitqueue;
92static DECLARE_WAIT_QUEUE_HEAD(pipe_version_waitqueue); 92static DECLARE_WAIT_QUEUE_HEAD(pipe_version_waitqueue);
@@ -266,24 +266,27 @@ struct gss_upcall_msg {
266 char databuf[UPCALL_BUF_LEN]; 266 char databuf[UPCALL_BUF_LEN];
267}; 267};
268 268
269static int get_pipe_version(void) 269static int get_pipe_version(struct net *net)
270{ 270{
271 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
271 int ret; 272 int ret;
272 273
273 spin_lock(&pipe_version_lock); 274 spin_lock(&pipe_version_lock);
274 if (pipe_version >= 0) { 275 if (sn->pipe_version >= 0) {
275 atomic_inc(&pipe_users); 276 atomic_inc(&sn->pipe_users);
276 ret = pipe_version; 277 ret = sn->pipe_version;
277 } else 278 } else
278 ret = -EAGAIN; 279 ret = -EAGAIN;
279 spin_unlock(&pipe_version_lock); 280 spin_unlock(&pipe_version_lock);
280 return ret; 281 return ret;
281} 282}
282 283
283static void put_pipe_version(void) 284static void put_pipe_version(struct net *net)
284{ 285{
285 if (atomic_dec_and_lock(&pipe_users, &pipe_version_lock)) { 286 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
286 pipe_version = -1; 287
288 if (atomic_dec_and_lock(&sn->pipe_users, &pipe_version_lock)) {
289 sn->pipe_version = -1;
287 spin_unlock(&pipe_version_lock); 290 spin_unlock(&pipe_version_lock);
288 } 291 }
289} 292}
@@ -291,9 +294,10 @@ static void put_pipe_version(void)
291static void 294static void
292gss_release_msg(struct gss_upcall_msg *gss_msg) 295gss_release_msg(struct gss_upcall_msg *gss_msg)
293{ 296{
297 struct net *net = rpc_net_ns(gss_msg->auth->client);
294 if (!atomic_dec_and_test(&gss_msg->count)) 298 if (!atomic_dec_and_test(&gss_msg->count))
295 return; 299 return;
296 put_pipe_version(); 300 put_pipe_version(net);
297 BUG_ON(!list_empty(&gss_msg->list)); 301 BUG_ON(!list_empty(&gss_msg->list));
298 if (gss_msg->ctx != NULL) 302 if (gss_msg->ctx != NULL)
299 gss_put_ctx(gss_msg->ctx); 303 gss_put_ctx(gss_msg->ctx);
@@ -439,7 +443,10 @@ static void gss_encode_msg(struct gss_upcall_msg *gss_msg,
439 struct rpc_clnt *clnt, 443 struct rpc_clnt *clnt,
440 const char *service_name) 444 const char *service_name)
441{ 445{
442 if (pipe_version == 0) 446 struct net *net = rpc_net_ns(clnt);
447 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
448
449 if (sn->pipe_version == 0)
443 gss_encode_v0_msg(gss_msg); 450 gss_encode_v0_msg(gss_msg);
444 else /* pipe_version == 1 */ 451 else /* pipe_version == 1 */
445 gss_encode_v1_msg(gss_msg, clnt, service_name); 452 gss_encode_v1_msg(gss_msg, clnt, service_name);
@@ -455,7 +462,7 @@ gss_alloc_msg(struct gss_auth *gss_auth, struct rpc_clnt *clnt,
455 gss_msg = kzalloc(sizeof(*gss_msg), GFP_NOFS); 462 gss_msg = kzalloc(sizeof(*gss_msg), GFP_NOFS);
456 if (gss_msg == NULL) 463 if (gss_msg == NULL)
457 return ERR_PTR(-ENOMEM); 464 return ERR_PTR(-ENOMEM);
458 vers = get_pipe_version(); 465 vers = get_pipe_version(rpc_net_ns(clnt));
459 if (vers < 0) { 466 if (vers < 0) {
460 kfree(gss_msg); 467 kfree(gss_msg);
461 return ERR_PTR(vers); 468 return ERR_PTR(vers);
@@ -559,24 +566,34 @@ out:
559static inline int 566static inline int
560gss_create_upcall(struct gss_auth *gss_auth, struct gss_cred *gss_cred) 567gss_create_upcall(struct gss_auth *gss_auth, struct gss_cred *gss_cred)
561{ 568{
569 struct net *net = rpc_net_ns(gss_auth->client);
570 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
562 struct rpc_pipe *pipe; 571 struct rpc_pipe *pipe;
563 struct rpc_cred *cred = &gss_cred->gc_base; 572 struct rpc_cred *cred = &gss_cred->gc_base;
564 struct gss_upcall_msg *gss_msg; 573 struct gss_upcall_msg *gss_msg;
574 unsigned long timeout;
565 DEFINE_WAIT(wait); 575 DEFINE_WAIT(wait);
566 int err = 0; 576 int err;
567 577
568 dprintk("RPC: %s for uid %u\n", 578 dprintk("RPC: %s for uid %u\n",
569 __func__, from_kuid(&init_user_ns, cred->cr_uid)); 579 __func__, from_kuid(&init_user_ns, cred->cr_uid));
570retry: 580retry:
581 err = 0;
582 /* Default timeout is 15s unless we know that gssd is not running */
583 timeout = 15 * HZ;
584 if (!sn->gssd_running)
585 timeout = HZ >> 2;
571 gss_msg = gss_setup_upcall(gss_auth->client, gss_auth, cred); 586 gss_msg = gss_setup_upcall(gss_auth->client, gss_auth, cred);
572 if (PTR_ERR(gss_msg) == -EAGAIN) { 587 if (PTR_ERR(gss_msg) == -EAGAIN) {
573 err = wait_event_interruptible_timeout(pipe_version_waitqueue, 588 err = wait_event_interruptible_timeout(pipe_version_waitqueue,
574 pipe_version >= 0, 15*HZ); 589 sn->pipe_version >= 0, timeout);
575 if (pipe_version < 0) { 590 if (sn->pipe_version < 0) {
591 if (err == 0)
592 sn->gssd_running = 0;
576 warn_gssd(); 593 warn_gssd();
577 err = -EACCES; 594 err = -EACCES;
578 } 595 }
579 if (err) 596 if (err < 0)
580 goto out; 597 goto out;
581 goto retry; 598 goto retry;
582 } 599 }
@@ -707,20 +724,22 @@ out:
707 724
708static int gss_pipe_open(struct inode *inode, int new_version) 725static int gss_pipe_open(struct inode *inode, int new_version)
709{ 726{
727 struct net *net = inode->i_sb->s_fs_info;
728 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
710 int ret = 0; 729 int ret = 0;
711 730
712 spin_lock(&pipe_version_lock); 731 spin_lock(&pipe_version_lock);
713 if (pipe_version < 0) { 732 if (sn->pipe_version < 0) {
714 /* First open of any gss pipe determines the version: */ 733 /* First open of any gss pipe determines the version: */
715 pipe_version = new_version; 734 sn->pipe_version = new_version;
716 rpc_wake_up(&pipe_version_rpc_waitqueue); 735 rpc_wake_up(&pipe_version_rpc_waitqueue);
717 wake_up(&pipe_version_waitqueue); 736 wake_up(&pipe_version_waitqueue);
718 } else if (pipe_version != new_version) { 737 } else if (sn->pipe_version != new_version) {
719 /* Trying to open a pipe of a different version */ 738 /* Trying to open a pipe of a different version */
720 ret = -EBUSY; 739 ret = -EBUSY;
721 goto out; 740 goto out;
722 } 741 }
723 atomic_inc(&pipe_users); 742 atomic_inc(&sn->pipe_users);
724out: 743out:
725 spin_unlock(&pipe_version_lock); 744 spin_unlock(&pipe_version_lock);
726 return ret; 745 return ret;
@@ -740,6 +759,7 @@ static int gss_pipe_open_v1(struct inode *inode)
740static void 759static void
741gss_pipe_release(struct inode *inode) 760gss_pipe_release(struct inode *inode)
742{ 761{
762 struct net *net = inode->i_sb->s_fs_info;
743 struct rpc_pipe *pipe = RPC_I(inode)->pipe; 763 struct rpc_pipe *pipe = RPC_I(inode)->pipe;
744 struct gss_upcall_msg *gss_msg; 764 struct gss_upcall_msg *gss_msg;
745 765
@@ -758,7 +778,7 @@ restart:
758 } 778 }
759 spin_unlock(&pipe->lock); 779 spin_unlock(&pipe->lock);
760 780
761 put_pipe_version(); 781 put_pipe_version(net);
762} 782}
763 783
764static void 784static void
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 5a750b9c3640..f0339ae9bf37 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -157,20 +157,15 @@ static struct dentry *rpc_setup_pipedir_sb(struct super_block *sb,
157} 157}
158 158
159static int 159static int
160rpc_setup_pipedir(struct rpc_clnt *clnt, const char *dir_name) 160rpc_setup_pipedir(struct rpc_clnt *clnt, const char *dir_name,
161 struct super_block *pipefs_sb)
161{ 162{
162 struct net *net = rpc_net_ns(clnt);
163 struct super_block *pipefs_sb;
164 struct dentry *dentry; 163 struct dentry *dentry;
165 164
166 clnt->cl_dentry = NULL; 165 clnt->cl_dentry = NULL;
167 if (dir_name == NULL) 166 if (dir_name == NULL)
168 return 0; 167 return 0;
169 pipefs_sb = rpc_get_sb_net(net);
170 if (!pipefs_sb)
171 return 0;
172 dentry = rpc_setup_pipedir_sb(pipefs_sb, clnt, dir_name); 168 dentry = rpc_setup_pipedir_sb(pipefs_sb, clnt, dir_name);
173 rpc_put_sb_net(net);
174 if (IS_ERR(dentry)) 169 if (IS_ERR(dentry))
175 return PTR_ERR(dentry); 170 return PTR_ERR(dentry);
176 clnt->cl_dentry = dentry; 171 clnt->cl_dentry = dentry;
@@ -182,6 +177,8 @@ static inline int rpc_clnt_skip_event(struct rpc_clnt *clnt, unsigned long event
182 if (((event == RPC_PIPEFS_MOUNT) && clnt->cl_dentry) || 177 if (((event == RPC_PIPEFS_MOUNT) && clnt->cl_dentry) ||
183 ((event == RPC_PIPEFS_UMOUNT) && !clnt->cl_dentry)) 178 ((event == RPC_PIPEFS_UMOUNT) && !clnt->cl_dentry))
184 return 1; 179 return 1;
180 if ((event == RPC_PIPEFS_MOUNT) && atomic_read(&clnt->cl_count) == 0)
181 return 1;
185 return 0; 182 return 0;
186} 183}
187 184
@@ -241,8 +238,6 @@ static struct rpc_clnt *rpc_get_client_for_event(struct net *net, int event)
241 continue; 238 continue;
242 if (rpc_clnt_skip_event(clnt, event)) 239 if (rpc_clnt_skip_event(clnt, event))
243 continue; 240 continue;
244 if (atomic_inc_not_zero(&clnt->cl_count) == 0)
245 continue;
246 spin_unlock(&sn->rpc_client_lock); 241 spin_unlock(&sn->rpc_client_lock);
247 return clnt; 242 return clnt;
248 } 243 }
@@ -259,7 +254,6 @@ static int rpc_pipefs_event(struct notifier_block *nb, unsigned long event,
259 254
260 while ((clnt = rpc_get_client_for_event(sb->s_fs_info, event))) { 255 while ((clnt = rpc_get_client_for_event(sb->s_fs_info, event))) {
261 error = __rpc_pipefs_event(clnt, event, sb); 256 error = __rpc_pipefs_event(clnt, event, sb);
262 rpc_release_client(clnt);
263 if (error) 257 if (error)
264 break; 258 break;
265 } 259 }
@@ -289,12 +283,46 @@ static void rpc_clnt_set_nodename(struct rpc_clnt *clnt, const char *nodename)
289 memcpy(clnt->cl_nodename, nodename, clnt->cl_nodelen); 283 memcpy(clnt->cl_nodename, nodename, clnt->cl_nodelen);
290} 284}
291 285
286static int rpc_client_register(const struct rpc_create_args *args,
287 struct rpc_clnt *clnt)
288{
289 const struct rpc_program *program = args->program;
290 struct rpc_auth *auth;
291 struct net *net = rpc_net_ns(clnt);
292 struct super_block *pipefs_sb;
293 int err = 0;
294
295 pipefs_sb = rpc_get_sb_net(net);
296 if (pipefs_sb) {
297 err = rpc_setup_pipedir(clnt, program->pipe_dir_name, pipefs_sb);
298 if (err)
299 goto out;
300 }
301
302 auth = rpcauth_create(args->authflavor, clnt);
303 if (IS_ERR(auth)) {
304 dprintk("RPC: Couldn't create auth handle (flavor %u)\n",
305 args->authflavor);
306 err = PTR_ERR(auth);
307 goto err_auth;
308 }
309
310 rpc_register_client(clnt);
311out:
312 if (pipefs_sb)
313 rpc_put_sb_net(net);
314 return err;
315
316err_auth:
317 __rpc_clnt_remove_pipedir(clnt);
318 goto out;
319}
320
292static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, struct rpc_xprt *xprt) 321static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, struct rpc_xprt *xprt)
293{ 322{
294 const struct rpc_program *program = args->program; 323 const struct rpc_program *program = args->program;
295 const struct rpc_version *version; 324 const struct rpc_version *version;
296 struct rpc_clnt *clnt = NULL; 325 struct rpc_clnt *clnt = NULL;
297 struct rpc_auth *auth;
298 int err; 326 int err;
299 327
300 /* sanity check the name before trying to print it */ 328 /* sanity check the name before trying to print it */
@@ -354,25 +382,14 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, stru
354 382
355 atomic_set(&clnt->cl_count, 1); 383 atomic_set(&clnt->cl_count, 1);
356 384
357 err = rpc_setup_pipedir(clnt, program->pipe_dir_name);
358 if (err < 0)
359 goto out_no_path;
360
361 auth = rpcauth_create(args->authflavor, clnt);
362 if (IS_ERR(auth)) {
363 dprintk("RPC: Couldn't create auth handle (flavor %u)\n",
364 args->authflavor);
365 err = PTR_ERR(auth);
366 goto out_no_auth;
367 }
368
369 /* save the nodename */ 385 /* save the nodename */
370 rpc_clnt_set_nodename(clnt, utsname()->nodename); 386 rpc_clnt_set_nodename(clnt, utsname()->nodename);
371 rpc_register_client(clnt); 387
388 err = rpc_client_register(args, clnt);
389 if (err)
390 goto out_no_path;
372 return clnt; 391 return clnt;
373 392
374out_no_auth:
375 rpc_clnt_remove_pipedir(clnt);
376out_no_path: 393out_no_path:
377 kfree(clnt->cl_principal); 394 kfree(clnt->cl_principal);
378out_no_principal: 395out_no_principal:
@@ -637,8 +654,8 @@ rpc_free_client(struct rpc_clnt *clnt)
637 rcu_dereference(clnt->cl_xprt)->servername); 654 rcu_dereference(clnt->cl_xprt)->servername);
638 if (clnt->cl_parent != clnt) 655 if (clnt->cl_parent != clnt)
639 rpc_release_client(clnt->cl_parent); 656 rpc_release_client(clnt->cl_parent);
640 rpc_unregister_client(clnt);
641 rpc_clnt_remove_pipedir(clnt); 657 rpc_clnt_remove_pipedir(clnt);
658 rpc_unregister_client(clnt);
642 rpc_free_iostats(clnt->cl_metrics); 659 rpc_free_iostats(clnt->cl_metrics);
643 kfree(clnt->cl_principal); 660 kfree(clnt->cl_principal);
644 clnt->cl_metrics = NULL; 661 clnt->cl_metrics = NULL;
diff --git a/net/sunrpc/netns.h b/net/sunrpc/netns.h
index 7111a4c9113b..74d948f5d5a1 100644
--- a/net/sunrpc/netns.h
+++ b/net/sunrpc/netns.h
@@ -28,7 +28,11 @@ struct sunrpc_net {
28 wait_queue_head_t gssp_wq; 28 wait_queue_head_t gssp_wq;
29 struct rpc_clnt *gssp_clnt; 29 struct rpc_clnt *gssp_clnt;
30 int use_gss_proxy; 30 int use_gss_proxy;
31 int pipe_version;
32 atomic_t pipe_users;
31 struct proc_dir_entry *use_gssp_proc; 33 struct proc_dir_entry *use_gssp_proc;
34
35 unsigned int gssd_running;
32}; 36};
33 37
34extern int sunrpc_net_id; 38extern int sunrpc_net_id;
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index a9129f8d7070..4679df5a6d50 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -216,11 +216,14 @@ rpc_destroy_inode(struct inode *inode)
216static int 216static int
217rpc_pipe_open(struct inode *inode, struct file *filp) 217rpc_pipe_open(struct inode *inode, struct file *filp)
218{ 218{
219 struct net *net = inode->i_sb->s_fs_info;
220 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
219 struct rpc_pipe *pipe; 221 struct rpc_pipe *pipe;
220 int first_open; 222 int first_open;
221 int res = -ENXIO; 223 int res = -ENXIO;
222 224
223 mutex_lock(&inode->i_mutex); 225 mutex_lock(&inode->i_mutex);
226 sn->gssd_running = 1;
224 pipe = RPC_I(inode)->pipe; 227 pipe = RPC_I(inode)->pipe;
225 if (pipe == NULL) 228 if (pipe == NULL)
226 goto out; 229 goto out;
@@ -664,7 +667,8 @@ static struct dentry *__rpc_lookup_create_exclusive(struct dentry *parent,
664 return ERR_PTR(-ENOMEM); 667 return ERR_PTR(-ENOMEM);
665 } 668 }
666 if (dentry->d_inode == NULL) { 669 if (dentry->d_inode == NULL) {
667 d_set_d_op(dentry, &rpc_dentry_operations); 670 if (!dentry->d_op)
671 d_set_d_op(dentry, &rpc_dentry_operations);
668 return dentry; 672 return dentry;
669 } 673 }
670 dput(dentry); 674 dput(dentry);
@@ -1069,6 +1073,8 @@ void rpc_pipefs_init_net(struct net *net)
1069 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); 1073 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
1070 1074
1071 mutex_init(&sn->pipefs_sb_lock); 1075 mutex_init(&sn->pipefs_sb_lock);
1076 sn->gssd_running = 1;
1077 sn->pipe_version = -1;
1072} 1078}
1073 1079
1074/* 1080/*
@@ -1121,6 +1127,7 @@ rpc_fill_super(struct super_block *sb, void *data, int silent)
1121 return -ENOMEM; 1127 return -ENOMEM;
1122 dprintk("RPC: sending pipefs MOUNT notification for net %p%s\n", 1128 dprintk("RPC: sending pipefs MOUNT notification for net %p%s\n",
1123 net, NET_NAME(net)); 1129 net, NET_NAME(net));
1130 mutex_lock(&sn->pipefs_sb_lock);
1124 sn->pipefs_sb = sb; 1131 sn->pipefs_sb = sb;
1125 err = blocking_notifier_call_chain(&rpc_pipefs_notifier_list, 1132 err = blocking_notifier_call_chain(&rpc_pipefs_notifier_list,
1126 RPC_PIPEFS_MOUNT, 1133 RPC_PIPEFS_MOUNT,
@@ -1128,6 +1135,7 @@ rpc_fill_super(struct super_block *sb, void *data, int silent)
1128 if (err) 1135 if (err)
1129 goto err_depopulate; 1136 goto err_depopulate;
1130 sb->s_fs_info = get_net(net); 1137 sb->s_fs_info = get_net(net);
1138 mutex_unlock(&sn->pipefs_sb_lock);
1131 return 0; 1139 return 0;
1132 1140
1133err_depopulate: 1141err_depopulate:
@@ -1136,6 +1144,7 @@ err_depopulate:
1136 sb); 1144 sb);
1137 sn->pipefs_sb = NULL; 1145 sn->pipefs_sb = NULL;
1138 __rpc_depopulate(root, files, RPCAUTH_lockd, RPCAUTH_RootEOF); 1146 __rpc_depopulate(root, files, RPCAUTH_lockd, RPCAUTH_RootEOF);
1147 mutex_unlock(&sn->pipefs_sb_lock);
1139 return err; 1148 return err;
1140} 1149}
1141 1150
@@ -1157,12 +1166,12 @@ static void rpc_kill_sb(struct super_block *sb)
1157 goto out; 1166 goto out;
1158 } 1167 }
1159 sn->pipefs_sb = NULL; 1168 sn->pipefs_sb = NULL;
1160 mutex_unlock(&sn->pipefs_sb_lock);
1161 dprintk("RPC: sending pipefs UMOUNT notification for net %p%s\n", 1169 dprintk("RPC: sending pipefs UMOUNT notification for net %p%s\n",
1162 net, NET_NAME(net)); 1170 net, NET_NAME(net));
1163 blocking_notifier_call_chain(&rpc_pipefs_notifier_list, 1171 blocking_notifier_call_chain(&rpc_pipefs_notifier_list,
1164 RPC_PIPEFS_UMOUNT, 1172 RPC_PIPEFS_UMOUNT,
1165 sb); 1173 sb);
1174 mutex_unlock(&sn->pipefs_sb_lock);
1166 put_net(net); 1175 put_net(net);
1167out: 1176out:
1168 kill_litter_super(sb); 1177 kill_litter_super(sb);
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
index f8529fc8e542..b7b32c34c18d 100644
--- a/net/sunrpc/sched.c
+++ b/net/sunrpc/sched.c
@@ -324,11 +324,17 @@ EXPORT_SYMBOL_GPL(__rpc_wait_for_completion_task);
324 * Note: If the task is ASYNC, and is being made runnable after sitting on an 324 * Note: If the task is ASYNC, and is being made runnable after sitting on an
325 * rpc_wait_queue, this must be called with the queue spinlock held to protect 325 * rpc_wait_queue, this must be called with the queue spinlock held to protect
326 * the wait queue operation. 326 * the wait queue operation.
327 * Note the ordering of rpc_test_and_set_running() and rpc_clear_queued(),
328 * which is needed to ensure that __rpc_execute() doesn't loop (due to the
329 * lockless RPC_IS_QUEUED() test) before we've had a chance to test
330 * the RPC_TASK_RUNNING flag.
327 */ 331 */
328static void rpc_make_runnable(struct rpc_task *task) 332static void rpc_make_runnable(struct rpc_task *task)
329{ 333{
334 bool need_wakeup = !rpc_test_and_set_running(task);
335
330 rpc_clear_queued(task); 336 rpc_clear_queued(task);
331 if (rpc_test_and_set_running(task)) 337 if (!need_wakeup)
332 return; 338 return;
333 if (RPC_IS_ASYNC(task)) { 339 if (RPC_IS_ASYNC(task)) {
334 INIT_WORK(&task->u.tk_work, rpc_async_schedule); 340 INIT_WORK(&task->u.tk_work, rpc_async_schedule);
@@ -440,20 +446,6 @@ static void rpc_wake_up_task_queue_locked(struct rpc_wait_queue *queue, struct r
440} 446}
441 447
442/* 448/*
443 * Tests whether rpc queue is empty
444 */
445int rpc_queue_empty(struct rpc_wait_queue *queue)
446{
447 int res;
448
449 spin_lock_bh(&queue->lock);
450 res = queue->qlen;
451 spin_unlock_bh(&queue->lock);
452 return res == 0;
453}
454EXPORT_SYMBOL_GPL(rpc_queue_empty);
455
456/*
457 * Wake up a task on a specific queue 449 * Wake up a task on a specific queue
458 */ 450 */
459void rpc_wake_up_queued_task(struct rpc_wait_queue *queue, struct rpc_task *task) 451void rpc_wake_up_queued_task(struct rpc_wait_queue *queue, struct rpc_task *task)
@@ -798,7 +790,6 @@ static void __rpc_execute(struct rpc_task *task)
798 task->tk_flags |= RPC_TASK_KILLED; 790 task->tk_flags |= RPC_TASK_KILLED;
799 rpc_exit(task, -ERESTARTSYS); 791 rpc_exit(task, -ERESTARTSYS);
800 } 792 }
801 rpc_set_running(task);
802 dprintk("RPC: %5u sync task resuming\n", task->tk_pid); 793 dprintk("RPC: %5u sync task resuming\n", task->tk_pid);
803 } 794 }
804 795
@@ -819,9 +810,11 @@ static void __rpc_execute(struct rpc_task *task)
819 */ 810 */
820void rpc_execute(struct rpc_task *task) 811void rpc_execute(struct rpc_task *task)
821{ 812{
813 bool is_async = RPC_IS_ASYNC(task);
814
822 rpc_set_active(task); 815 rpc_set_active(task);
823 rpc_make_runnable(task); 816 rpc_make_runnable(task);
824 if (!RPC_IS_ASYNC(task)) 817 if (!is_async)
825 __rpc_execute(task); 818 __rpc_execute(task);
826} 819}
827 820