Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Chuck Lever and committed by
Trond Myklebust
8cab4c39 f411703a

+46 -37
+42 -34
fs/nfs/client.c
··· 546 546 int noresvport) 547 547 { 548 548 struct nfs_client *clp, *new = NULL; 549 - int error; 550 549 struct nfs_net *nn = net_generic(cl_init->net, nfs_net_id); 551 550 552 551 dprintk("--> nfs_get_client(%s,v%u)\n", ··· 562 563 nfs_free_client(new); 563 564 return nfs_found_client(cl_init, clp); 564 565 } 565 - if (new) 566 - goto install_client; 566 + if (new) { 567 + list_add(&new->cl_share_link, &nn->nfs_client_list); 568 + spin_unlock(&nn->nfs_client_lock); 569 + return cl_init->rpc_ops->init_client(new, 570 + timeparms, ip_addr, 571 + authflavour, noresvport); 572 + } 567 573 568 574 spin_unlock(&nn->nfs_client_lock); 569 575 ··· 578 574 dprintk("<-- nfs_get_client() Failed to find %s (%ld)\n", 579 575 cl_init->hostname ?: "", PTR_ERR(new)); 580 576 return new; 581 - 582 - /* install a new client and return with it unready */ 583 - install_client: 584 - clp = new; 585 - list_add(&clp->cl_share_link, &nn->nfs_client_list); 586 - spin_unlock(&nn->nfs_client_lock); 587 - 588 - error = cl_init->rpc_ops->init_client(clp, timeparms, ip_addr, 589 - authflavour, noresvport); 590 - if (error < 0) { 591 - nfs_put_client(clp); 592 - return ERR_PTR(error); 593 - } 594 - dprintk("--> nfs_get_client() = %p [new]\n", clp); 595 - return clp; 596 577 } 597 578 598 579 /* ··· 802 813 return 0; 803 814 } 804 815 805 - /* 806 - * Initialise an NFS2 or NFS3 client 816 + /** 817 + * nfs_init_client - Initialise an NFS2 or NFS3 client 818 + * 819 + * @clp: nfs_client to initialise 820 + * @timeparms: timeout parameters for underlying RPC transport 821 + * @ip_addr: IP presentation address (not used) 822 + * @authflavor: authentication flavor for underlying RPC transport 823 + * @noresvport: set if RPC transport can use an ephemeral source port 824 + * 825 + * Returns pointer to an NFS client, or an ERR_PTR value. 807 826 */ 808 - int nfs_init_client(struct nfs_client *clp, const struct rpc_timeout *timeparms, 827 + struct nfs_client *nfs_init_client(struct nfs_client *clp, 828 + const struct rpc_timeout *timeparms, 809 829 const char *ip_addr, rpc_authflavor_t authflavour, 810 830 int noresvport) 811 831 { ··· 823 825 if (clp->cl_cons_state == NFS_CS_READY) { 824 826 /* the client is already initialised */ 825 827 dprintk("<-- nfs_init_client() = 0 [already %p]\n", clp); 826 - return 0; 828 + return clp; 827 829 } 828 830 829 831 /* ··· 835 837 if (error < 0) 836 838 goto error; 837 839 nfs_mark_client_ready(clp, NFS_CS_READY); 838 - return 0; 840 + return clp; 839 841 840 842 error: 841 843 nfs_mark_client_ready(clp, error); 844 + nfs_put_client(clp); 842 845 dprintk("<-- nfs_init_client() = xerror %d\n", error); 843 - return error; 846 + return ERR_PTR(error); 844 847 } 845 848 846 849 /* ··· 1357 1358 return nfs4_init_callback(clp); 1358 1359 } 1359 1360 1360 - /* 1361 - * Initialise an NFS4 client record 1361 + /** 1362 + * nfs4_init_client - Initialise an NFS4 client record 1363 + * 1364 + * @clp: nfs_client to initialise 1365 + * @timeparms: timeout parameters for underlying RPC transport 1366 + * @ip_addr: callback IP address in presentation format 1367 + * @authflavor: authentication flavor for underlying RPC transport 1368 + * @noresvport: set if RPC transport can use an ephemeral source port 1369 + * 1370 + * Returns pointer to an NFS client, or an ERR_PTR value. 1362 1371 */ 1363 - int nfs4_init_client(struct nfs_client *clp, 1364 - const struct rpc_timeout *timeparms, 1365 - const char *ip_addr, 1366 - rpc_authflavor_t authflavour, 1367 - int noresvport) 1372 + struct nfs_client *nfs4_init_client(struct nfs_client *clp, 1373 + const struct rpc_timeout *timeparms, 1374 + const char *ip_addr, 1375 + rpc_authflavor_t authflavour, 1376 + int noresvport) 1368 1377 { 1369 1378 char buf[INET6_ADDRSTRLEN + 1]; 1370 1379 int error; ··· 1380 1373 if (clp->cl_cons_state == NFS_CS_READY) { 1381 1374 /* the client is initialised already */ 1382 1375 dprintk("<-- nfs4_init_client() = 0 [already %p]\n", clp); 1383 - return 0; 1376 + return clp; 1384 1377 } 1385 1378 1386 1379 /* Check NFS protocol revision and initialize RPC op vector */ ··· 1420 1413 1421 1414 if (!nfs4_has_session(clp)) 1422 1415 nfs_mark_client_ready(clp, NFS_CS_READY); 1423 - return 0; 1416 + return clp; 1424 1417 1425 1418 error: 1426 1419 nfs_mark_client_ready(clp, error); 1420 + nfs_put_client(clp); 1427 1421 dprintk("<-- nfs4_init_client() = xerror %d\n", error); 1428 - return error; 1422 + return ERR_PTR(error); 1429 1423 } 1430 1424 1431 1425 /*
+2 -2
fs/nfs/internal.h
··· 238 238 239 239 /* proc.c */ 240 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 242 const struct rpc_timeout *timeparms, 243 243 const char *ip_addr, rpc_authflavor_t authflavour, 244 244 int noresvport); ··· 373 373 374 374 /* nfs4proc.c */ 375 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 377 const struct rpc_timeout *timeparms, 378 378 const char *ip_addr, 379 379 rpc_authflavor_t authflavour,
+2 -1
include/linux/nfs_xdr.h
··· 1397 1397 struct nfs_open_context *ctx, 1398 1398 int open_flags, 1399 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 1402 const char *, rpc_authflavor_t, int); 1402 1403 }; 1403 1404