diff options
author | Chuck Lever <chuck.lever@oracle.com> | 2012-05-21 22:45:59 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2012-05-22 16:45:47 -0400 |
commit | 8cab4c390b43fe34c07bd33799c1bc24be648122 (patch) | |
tree | a819ca042219e2764b9042e410ed6f7b4354c59b | |
parent | f411703adc762a92b72f8a93c6464050d66cb87b (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.c | 76 | ||||
-rw-r--r-- | fs/nfs/internal.h | 4 | ||||
-rw-r--r-- | include/linux/nfs_xdr.h | 3 |
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 */ | ||
579 | install_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 | */ |
819 | int nfs_init_client(struct nfs_client *clp, const struct rpc_timeout *timeparms, | 816 | struct 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 | ||
842 | error: | 840 | error: |
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 | */ |
1364 | int nfs4_init_client(struct nfs_client *clp, | 1371 | struct 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 | ||
1418 | error: | 1425 | error: |
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 */ |
240 | void nfs_close_context(struct nfs_open_context *ctx, int is_sync); | 240 | void nfs_close_context(struct nfs_open_context *ctx, int is_sync); |
241 | extern int nfs_init_client(struct nfs_client *clp, | 241 | extern 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 */ |
375 | extern void __nfs4_read_done_cb(struct nfs_read_data *); | 375 | extern void __nfs4_read_done_cb(struct nfs_read_data *); |
376 | extern int nfs4_init_client(struct nfs_client *clp, | 376 | extern 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 | ||