aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2012-05-21 22:45:59 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2012-05-22 16:45:47 -0400
commit8cab4c390b43fe34c07bd33799c1bc24be648122 (patch)
treea819ca042219e2764b9042e410ed6f7b4354c59b
parentf411703adc762a92b72f8a93c6464050d66cb87b (diff)
NFS: Refactor nfs_get_client(): initialize nfs_client
Clean up: Continue to rationalize the locking in nfs_get_client() by moving the logic that handles the case where a matching server IP address is not found. When we support server trunking detection, client initialization may return a different nfs_client struct than was passed to it. Change the synopsis of the init_client methods to return an nfs_client. The client initialization logic in nfs_get_client() is not much more than a wrapper around ->init_client. It's simpler to keep the little bits of error handling in the version-specific init_client methods. No behavior change is expected. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r--fs/nfs/client.c76
-rw-r--r--fs/nfs/internal.h4
-rw-r--r--include/linux/nfs_xdr.h3
3 files changed, 46 insertions, 37 deletions
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 5f19f9577730..8a4b3c2c5a2b 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -546,7 +546,6 @@ nfs_get_client(const struct nfs_client_initdata *cl_init,
546 int noresvport) 546 int noresvport)
547{ 547{
548 struct nfs_client *clp, *new = NULL; 548 struct nfs_client *clp, *new = NULL;
549 int error;
550 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);
551 550
552 dprintk("--> nfs_get_client(%s,v%u)\n", 551 dprintk("--> nfs_get_client(%s,v%u)\n",
@@ -563,8 +562,13 @@ nfs_get_client(const struct nfs_client_initdata *cl_init,
563 nfs_free_client(new); 562 nfs_free_client(new);
564 return nfs_found_client(cl_init, clp); 563 return nfs_found_client(cl_init, clp);
565 } 564 }
566 if (new) 565 if (new) {
567 goto install_client; 566 list_add(&new->cl_share_link, &nn->nfs_client_list);
567 spin_unlock(&nn->nfs_client_lock);
568 return cl_init->rpc_ops->init_client(new,
569 timeparms, ip_addr,
570 authflavour, noresvport);
571 }
568 572
569 spin_unlock(&nn->nfs_client_lock); 573 spin_unlock(&nn->nfs_client_lock);
570 574
@@ -574,21 +578,6 @@ nfs_get_client(const struct nfs_client_initdata *cl_init,
574 dprintk("<-- nfs_get_client() Failed to find %s (%ld)\n", 578 dprintk("<-- nfs_get_client() Failed to find %s (%ld)\n",
575 cl_init->hostname ?: "", PTR_ERR(new)); 579 cl_init->hostname ?: "", PTR_ERR(new));
576 return new; 580 return new;
577
578 /* install a new client and return with it unready */
579install_client:
580 clp = new;
581 list_add(&clp->cl_share_link, &nn->nfs_client_list);
582 spin_unlock(&nn->nfs_client_lock);
583
584 error = cl_init->rpc_ops->init_client(clp, timeparms, ip_addr,
585 authflavour, noresvport);
586 if (error < 0) {
587 nfs_put_client(clp);
588 return ERR_PTR(error);
589 }
590 dprintk("--> nfs_get_client() = %p [new]\n", clp);
591 return clp;
592} 581}
593 582
594/* 583/*
@@ -813,10 +802,19 @@ static int nfs_init_server_rpcclient(struct nfs_server *server,
813 return 0; 802 return 0;
814} 803}
815 804
816/* 805/**
817 * Initialise an NFS2 or NFS3 client 806 * nfs_init_client - Initialise an NFS2 or NFS3 client
807 *
808 * @clp: nfs_client to initialise
809 * @timeparms: timeout parameters for underlying RPC transport
810 * @ip_addr: IP presentation address (not used)
811 * @authflavor: authentication flavor for underlying RPC transport
812 * @noresvport: set if RPC transport can use an ephemeral source port
813 *
814 * Returns pointer to an NFS client, or an ERR_PTR value.
818 */ 815 */
819int nfs_init_client(struct nfs_client *clp, const struct rpc_timeout *timeparms, 816struct nfs_client *nfs_init_client(struct nfs_client *clp,
817 const struct rpc_timeout *timeparms,
820 const char *ip_addr, rpc_authflavor_t authflavour, 818 const char *ip_addr, rpc_authflavor_t authflavour,
821 int noresvport) 819 int noresvport)
822{ 820{
@@ -825,7 +823,7 @@ int nfs_init_client(struct nfs_client *clp, const struct rpc_timeout *timeparms,
825 if (clp->cl_cons_state == NFS_CS_READY) { 823 if (clp->cl_cons_state == NFS_CS_READY) {
826 /* the client is already initialised */ 824 /* the client is already initialised */
827 dprintk("<-- nfs_init_client() = 0 [already %p]\n", clp); 825 dprintk("<-- nfs_init_client() = 0 [already %p]\n", clp);
828 return 0; 826 return clp;
829 } 827 }
830 828
831 /* 829 /*
@@ -837,12 +835,13 @@ int nfs_init_client(struct nfs_client *clp, const struct rpc_timeout *timeparms,
837 if (error < 0) 835 if (error < 0)
838 goto error; 836 goto error;
839 nfs_mark_client_ready(clp, NFS_CS_READY); 837 nfs_mark_client_ready(clp, NFS_CS_READY);
840 return 0; 838 return clp;
841 839
842error: 840error:
843 nfs_mark_client_ready(clp, error); 841 nfs_mark_client_ready(clp, error);
842 nfs_put_client(clp);
844 dprintk("<-- nfs_init_client() = xerror %d\n", error); 843 dprintk("<-- nfs_init_client() = xerror %d\n", error);
845 return error; 844 return ERR_PTR(error);
846} 845}
847 846
848/* 847/*
@@ -1358,14 +1357,22 @@ static int nfs4_init_client_minor_version(struct nfs_client *clp)
1358 return nfs4_init_callback(clp); 1357 return nfs4_init_callback(clp);
1359} 1358}
1360 1359
1361/* 1360/**
1362 * Initialise an NFS4 client record 1361 * nfs4_init_client - Initialise an NFS4 client record
1362 *
1363 * @clp: nfs_client to initialise
1364 * @timeparms: timeout parameters for underlying RPC transport
1365 * @ip_addr: callback IP address in presentation format
1366 * @authflavor: authentication flavor for underlying RPC transport
1367 * @noresvport: set if RPC transport can use an ephemeral source port
1368 *
1369 * Returns pointer to an NFS client, or an ERR_PTR value.
1363 */ 1370 */
1364int nfs4_init_client(struct nfs_client *clp, 1371struct nfs_client *nfs4_init_client(struct nfs_client *clp,
1365 const struct rpc_timeout *timeparms, 1372 const struct rpc_timeout *timeparms,
1366 const char *ip_addr, 1373 const char *ip_addr,
1367 rpc_authflavor_t authflavour, 1374 rpc_authflavor_t authflavour,
1368 int noresvport) 1375 int noresvport)
1369{ 1376{
1370 char buf[INET6_ADDRSTRLEN + 1]; 1377 char buf[INET6_ADDRSTRLEN + 1];
1371 int error; 1378 int error;
@@ -1373,7 +1380,7 @@ int nfs4_init_client(struct nfs_client *clp,
1373 if (clp->cl_cons_state == NFS_CS_READY) { 1380 if (clp->cl_cons_state == NFS_CS_READY) {
1374 /* the client is initialised already */ 1381 /* the client is initialised already */
1375 dprintk("<-- nfs4_init_client() = 0 [already %p]\n", clp); 1382 dprintk("<-- nfs4_init_client() = 0 [already %p]\n", clp);
1376 return 0; 1383 return clp;
1377 } 1384 }
1378 1385
1379 /* Check NFS protocol revision and initialize RPC op vector */ 1386 /* Check NFS protocol revision and initialize RPC op vector */
@@ -1413,12 +1420,13 @@ int nfs4_init_client(struct nfs_client *clp,
1413 1420
1414 if (!nfs4_has_session(clp)) 1421 if (!nfs4_has_session(clp))
1415 nfs_mark_client_ready(clp, NFS_CS_READY); 1422 nfs_mark_client_ready(clp, NFS_CS_READY);
1416 return 0; 1423 return clp;
1417 1424
1418error: 1425error:
1419 nfs_mark_client_ready(clp, error); 1426 nfs_mark_client_ready(clp, error);
1427 nfs_put_client(clp);
1420 dprintk("<-- nfs4_init_client() = xerror %d\n", error); 1428 dprintk("<-- nfs4_init_client() = xerror %d\n", error);
1421 return error; 1429 return ERR_PTR(error);
1422} 1430}
1423 1431
1424/* 1432/*
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index 989959a59f07..3a9e80c9524b 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -238,7 +238,7 @@ extern int nfs4_init_ds_session(struct nfs_client *clp);
238 238
239/* proc.c */ 239/* proc.c */
240void nfs_close_context(struct nfs_open_context *ctx, int is_sync); 240void nfs_close_context(struct nfs_open_context *ctx, int is_sync);
241extern int nfs_init_client(struct nfs_client *clp, 241extern struct nfs_client *nfs_init_client(struct nfs_client *clp,
242 const struct rpc_timeout *timeparms, 242 const struct rpc_timeout *timeparms,
243 const char *ip_addr, rpc_authflavor_t authflavour, 243 const char *ip_addr, rpc_authflavor_t authflavour,
244 int noresvport); 244 int noresvport);
@@ -373,7 +373,7 @@ void nfs_init_cinfo_from_dreq(struct nfs_commit_info *cinfo,
373 373
374/* nfs4proc.c */ 374/* nfs4proc.c */
375extern void __nfs4_read_done_cb(struct nfs_read_data *); 375extern void __nfs4_read_done_cb(struct nfs_read_data *);
376extern int nfs4_init_client(struct nfs_client *clp, 376extern struct nfs_client *nfs4_init_client(struct nfs_client *clp,
377 const struct rpc_timeout *timeparms, 377 const struct rpc_timeout *timeparms,
378 const char *ip_addr, 378 const char *ip_addr,
379 rpc_authflavor_t authflavour, 379 rpc_authflavor_t authflavour,
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index c420b8d60a55..0c521cd496a7 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -1397,7 +1397,8 @@ struct nfs_rpc_ops {
1397 struct nfs_open_context *ctx, 1397 struct nfs_open_context *ctx,
1398 int open_flags, 1398 int open_flags,
1399 struct iattr *iattr); 1399 struct iattr *iattr);
1400 int (*init_client) (struct nfs_client *, const struct rpc_timeout *, 1400 struct nfs_client *
1401 (*init_client) (struct nfs_client *, const struct rpc_timeout *,
1401 const char *, rpc_authflavor_t, int); 1402 const char *, rpc_authflavor_t, int);
1402}; 1403};
1403 1404