aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/client.c
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2012-05-21 22:46:07 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2012-05-22 16:45:47 -0400
commit4bf590e08f6db3395c181618a4c14f1c39b7c4af (patch)
treea55286e214564ef1bea4cb270258b75e849268c1 /fs/nfs/client.c
parent8cab4c390b43fe34c07bd33799c1bc24be648122 (diff)
NFS: Add nfs_client behavior flags
"noresvport" and "discrtry" can be passed to nfs_create_rpc_client() by setting flags in the passed-in nfs_client. This change makes it easy to add new flags. Note that these settings are now "sticky" over the lifetime of a struct nfs_client, and may even be copied when an nfs_client is cloned. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/client.c')
-rw-r--r--fs/nfs/client.c42
1 files changed, 20 insertions, 22 deletions
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 8a4b3c2c5a2b..34b2e68c5249 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -131,6 +131,7 @@ const struct rpc_program nfsacl_program = {
131#endif /* CONFIG_NFS_V3_ACL */ 131#endif /* CONFIG_NFS_V3_ACL */
132 132
133struct nfs_client_initdata { 133struct nfs_client_initdata {
134 unsigned long init_flags;
134 const char *hostname; 135 const char *hostname;
135 const struct sockaddr *addr; 136 const struct sockaddr *addr;
136 size_t addrlen; 137 size_t addrlen;
@@ -542,8 +543,7 @@ static struct nfs_client *
542nfs_get_client(const struct nfs_client_initdata *cl_init, 543nfs_get_client(const struct nfs_client_initdata *cl_init,
543 const struct rpc_timeout *timeparms, 544 const struct rpc_timeout *timeparms,
544 const char *ip_addr, 545 const char *ip_addr,
545 rpc_authflavor_t authflavour, 546 rpc_authflavor_t authflavour)
546 int noresvport)
547{ 547{
548 struct nfs_client *clp, *new = NULL; 548 struct nfs_client *clp, *new = NULL;
549 struct nfs_net *nn = net_generic(cl_init->net, nfs_net_id); 549 struct nfs_net *nn = net_generic(cl_init->net, nfs_net_id);
@@ -565,9 +565,10 @@ nfs_get_client(const struct nfs_client_initdata *cl_init,
565 if (new) { 565 if (new) {
566 list_add(&new->cl_share_link, &nn->nfs_client_list); 566 list_add(&new->cl_share_link, &nn->nfs_client_list);
567 spin_unlock(&nn->nfs_client_lock); 567 spin_unlock(&nn->nfs_client_lock);
568 new->cl_flags = cl_init->init_flags;
568 return cl_init->rpc_ops->init_client(new, 569 return cl_init->rpc_ops->init_client(new,
569 timeparms, ip_addr, 570 timeparms, ip_addr,
570 authflavour, noresvport); 571 authflavour);
571 } 572 }
572 573
573 spin_unlock(&nn->nfs_client_lock); 574 spin_unlock(&nn->nfs_client_lock);
@@ -651,8 +652,7 @@ static void nfs_init_timeout_values(struct rpc_timeout *to, int proto,
651 */ 652 */
652static int nfs_create_rpc_client(struct nfs_client *clp, 653static int nfs_create_rpc_client(struct nfs_client *clp,
653 const struct rpc_timeout *timeparms, 654 const struct rpc_timeout *timeparms,
654 rpc_authflavor_t flavor, 655 rpc_authflavor_t flavor)
655 int discrtry, int noresvport)
656{ 656{
657 struct rpc_clnt *clnt = NULL; 657 struct rpc_clnt *clnt = NULL;
658 struct rpc_create_args args = { 658 struct rpc_create_args args = {
@@ -667,9 +667,9 @@ static int nfs_create_rpc_client(struct nfs_client *clp,
667 .authflavor = flavor, 667 .authflavor = flavor,
668 }; 668 };
669 669
670 if (discrtry) 670 if (test_bit(NFS_CS_DISCRTRY, &clp->cl_flags))
671 args.flags |= RPC_CLNT_CREATE_DISCRTRY; 671 args.flags |= RPC_CLNT_CREATE_DISCRTRY;
672 if (noresvport) 672 if (test_bit(NFS_CS_NORESVPORT, &clp->cl_flags))
673 args.flags |= RPC_CLNT_CREATE_NONPRIVPORT; 673 args.flags |= RPC_CLNT_CREATE_NONPRIVPORT;
674 674
675 if (!IS_ERR(clp->cl_rpcclient)) 675 if (!IS_ERR(clp->cl_rpcclient))
@@ -809,14 +809,12 @@ static int nfs_init_server_rpcclient(struct nfs_server *server,
809 * @timeparms: timeout parameters for underlying RPC transport 809 * @timeparms: timeout parameters for underlying RPC transport
810 * @ip_addr: IP presentation address (not used) 810 * @ip_addr: IP presentation address (not used)
811 * @authflavor: authentication flavor for underlying RPC transport 811 * @authflavor: authentication flavor for underlying RPC transport
812 * @noresvport: set if RPC transport can use an ephemeral source port
813 * 812 *
814 * Returns pointer to an NFS client, or an ERR_PTR value. 813 * Returns pointer to an NFS client, or an ERR_PTR value.
815 */ 814 */
816struct nfs_client *nfs_init_client(struct nfs_client *clp, 815struct nfs_client *nfs_init_client(struct nfs_client *clp,
817 const struct rpc_timeout *timeparms, 816 const struct rpc_timeout *timeparms,
818 const char *ip_addr, rpc_authflavor_t authflavour, 817 const char *ip_addr, rpc_authflavor_t authflavour)
819 int noresvport)
820{ 818{
821 int error; 819 int error;
822 820
@@ -830,8 +828,7 @@ struct nfs_client *nfs_init_client(struct nfs_client *clp,
830 * Create a client RPC handle for doing FSSTAT with UNIX auth only 828 * Create a client RPC handle for doing FSSTAT with UNIX auth only
831 * - RFC 2623, sec 2.3.2 829 * - RFC 2623, sec 2.3.2
832 */ 830 */
833 error = nfs_create_rpc_client(clp, timeparms, RPC_AUTH_UNIX, 831 error = nfs_create_rpc_client(clp, timeparms, RPC_AUTH_UNIX);
834 0, noresvport);
835 if (error < 0) 832 if (error < 0)
836 goto error; 833 goto error;
837 nfs_mark_client_ready(clp, NFS_CS_READY); 834 nfs_mark_client_ready(clp, NFS_CS_READY);
@@ -881,10 +878,11 @@ static int nfs_init_server(struct nfs_server *server,
881 878
882 nfs_init_timeout_values(&timeparms, data->nfs_server.protocol, 879 nfs_init_timeout_values(&timeparms, data->nfs_server.protocol,
883 data->timeo, data->retrans); 880 data->timeo, data->retrans);
881 if (data->flags & NFS_MOUNT_NORESVPORT)
882 set_bit(NFS_CS_NORESVPORT, &cl_init.init_flags);
884 883
885 /* Allocate or find a client reference we can use */ 884 /* Allocate or find a client reference we can use */
886 clp = nfs_get_client(&cl_init, &timeparms, NULL, RPC_AUTH_UNIX, 885 clp = nfs_get_client(&cl_init, &timeparms, NULL, RPC_AUTH_UNIX);
887 data->flags & NFS_MOUNT_NORESVPORT);
888 if (IS_ERR(clp)) { 886 if (IS_ERR(clp)) {
889 dprintk("<-- nfs_init_server() = error %ld\n", PTR_ERR(clp)); 887 dprintk("<-- nfs_init_server() = error %ld\n", PTR_ERR(clp));
890 return PTR_ERR(clp); 888 return PTR_ERR(clp);
@@ -1364,15 +1362,13 @@ static int nfs4_init_client_minor_version(struct nfs_client *clp)
1364 * @timeparms: timeout parameters for underlying RPC transport 1362 * @timeparms: timeout parameters for underlying RPC transport
1365 * @ip_addr: callback IP address in presentation format 1363 * @ip_addr: callback IP address in presentation format
1366 * @authflavor: authentication flavor for underlying RPC transport 1364 * @authflavor: authentication flavor for underlying RPC transport
1367 * @noresvport: set if RPC transport can use an ephemeral source port
1368 * 1365 *
1369 * Returns pointer to an NFS client, or an ERR_PTR value. 1366 * Returns pointer to an NFS client, or an ERR_PTR value.
1370 */ 1367 */
1371struct nfs_client *nfs4_init_client(struct nfs_client *clp, 1368struct nfs_client *nfs4_init_client(struct nfs_client *clp,
1372 const struct rpc_timeout *timeparms, 1369 const struct rpc_timeout *timeparms,
1373 const char *ip_addr, 1370 const char *ip_addr,
1374 rpc_authflavor_t authflavour, 1371 rpc_authflavor_t authflavour)
1375 int noresvport)
1376{ 1372{
1377 char buf[INET6_ADDRSTRLEN + 1]; 1373 char buf[INET6_ADDRSTRLEN + 1];
1378 int error; 1374 int error;
@@ -1386,8 +1382,8 @@ struct nfs_client *nfs4_init_client(struct nfs_client *clp,
1386 /* Check NFS protocol revision and initialize RPC op vector */ 1382 /* Check NFS protocol revision and initialize RPC op vector */
1387 clp->rpc_ops = &nfs_v4_clientops; 1383 clp->rpc_ops = &nfs_v4_clientops;
1388 1384
1389 error = nfs_create_rpc_client(clp, timeparms, authflavour, 1385 __set_bit(NFS_CS_DISCRTRY, &clp->cl_flags);
1390 1, noresvport); 1386 error = nfs_create_rpc_client(clp, timeparms, authflavour);
1391 if (error < 0) 1387 if (error < 0)
1392 goto error; 1388 goto error;
1393 1389
@@ -1455,9 +1451,11 @@ static int nfs4_set_client(struct nfs_server *server,
1455 1451
1456 dprintk("--> nfs4_set_client()\n"); 1452 dprintk("--> nfs4_set_client()\n");
1457 1453
1454 if (server->flags & NFS_MOUNT_NORESVPORT)
1455 set_bit(NFS_CS_NORESVPORT, &cl_init.init_flags);
1456
1458 /* Allocate or find a client reference we can use */ 1457 /* Allocate or find a client reference we can use */
1459 clp = nfs_get_client(&cl_init, timeparms, ip_addr, authflavour, 1458 clp = nfs_get_client(&cl_init, timeparms, ip_addr, authflavour);
1460 server->flags & NFS_MOUNT_NORESVPORT);
1461 if (IS_ERR(clp)) { 1459 if (IS_ERR(clp)) {
1462 error = PTR_ERR(clp); 1460 error = PTR_ERR(clp);
1463 goto error; 1461 goto error;
@@ -1512,7 +1510,7 @@ struct nfs_client *nfs4_set_ds_client(struct nfs_client* mds_clp,
1512 */ 1510 */
1513 nfs_init_timeout_values(&ds_timeout, ds_proto, ds_timeo, ds_retrans); 1511 nfs_init_timeout_values(&ds_timeout, ds_proto, ds_timeo, ds_retrans);
1514 clp = nfs_get_client(&cl_init, &ds_timeout, mds_clp->cl_ipaddr, 1512 clp = nfs_get_client(&cl_init, &ds_timeout, mds_clp->cl_ipaddr,
1515 mds_clp->cl_rpcclient->cl_auth->au_flavor, 0); 1513 mds_clp->cl_rpcclient->cl_auth->au_flavor);
1516 1514
1517 dprintk("<-- %s %p\n", __func__, clp); 1515 dprintk("<-- %s %p\n", __func__, clp);
1518 return clp; 1516 return clp;