aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/client.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/client.c')
-rw-r--r--fs/nfs/client.c27
1 files changed, 18 insertions, 9 deletions
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 34c3996bd0f5..5fea638743e4 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -232,11 +232,15 @@ void nfs_put_client(struct nfs_client *clp)
232 * Find a client by address 232 * Find a client by address
233 * - caller must hold nfs_client_lock 233 * - caller must hold nfs_client_lock
234 */ 234 */
235static struct nfs_client *__nfs_find_client(const struct sockaddr_in *addr, int nfsversion) 235static struct nfs_client *__nfs_find_client(const struct sockaddr_in *addr, int nfsversion, int match_port)
236{ 236{
237 struct nfs_client *clp; 237 struct nfs_client *clp;
238 238
239 list_for_each_entry(clp, &nfs_client_list, cl_share_link) { 239 list_for_each_entry(clp, &nfs_client_list, cl_share_link) {
240 /* Don't match clients that failed to initialise properly */
241 if (clp->cl_cons_state < 0)
242 continue;
243
240 /* Different NFS versions cannot share the same nfs_client */ 244 /* Different NFS versions cannot share the same nfs_client */
241 if (clp->cl_nfsversion != nfsversion) 245 if (clp->cl_nfsversion != nfsversion)
242 continue; 246 continue;
@@ -245,7 +249,7 @@ static struct nfs_client *__nfs_find_client(const struct sockaddr_in *addr, int
245 sizeof(clp->cl_addr.sin_addr)) != 0) 249 sizeof(clp->cl_addr.sin_addr)) != 0)
246 continue; 250 continue;
247 251
248 if (clp->cl_addr.sin_port == addr->sin_port) 252 if (!match_port || clp->cl_addr.sin_port == addr->sin_port)
249 goto found; 253 goto found;
250 } 254 }
251 255
@@ -265,11 +269,12 @@ struct nfs_client *nfs_find_client(const struct sockaddr_in *addr, int nfsversio
265 struct nfs_client *clp; 269 struct nfs_client *clp;
266 270
267 spin_lock(&nfs_client_lock); 271 spin_lock(&nfs_client_lock);
268 clp = __nfs_find_client(addr, nfsversion); 272 clp = __nfs_find_client(addr, nfsversion, 0);
269 spin_unlock(&nfs_client_lock); 273 spin_unlock(&nfs_client_lock);
270 274 if (clp != NULL && clp->cl_cons_state != NFS_CS_READY) {
271 BUG_ON(clp && clp->cl_cons_state == 0); 275 nfs_put_client(clp);
272 276 clp = NULL;
277 }
273 return clp; 278 return clp;
274} 279}
275 280
@@ -292,7 +297,7 @@ static struct nfs_client *nfs_get_client(const char *hostname,
292 do { 297 do {
293 spin_lock(&nfs_client_lock); 298 spin_lock(&nfs_client_lock);
294 299
295 clp = __nfs_find_client(addr, nfsversion); 300 clp = __nfs_find_client(addr, nfsversion, 1);
296 if (clp) 301 if (clp)
297 goto found_client; 302 goto found_client;
298 if (new) 303 if (new)
@@ -849,6 +854,7 @@ error:
849 */ 854 */
850static int nfs4_init_client(struct nfs_client *clp, 855static int nfs4_init_client(struct nfs_client *clp,
851 int proto, int timeo, int retrans, 856 int proto, int timeo, int retrans,
857 const char *ip_addr,
852 rpc_authflavor_t authflavour) 858 rpc_authflavor_t authflavour)
853{ 859{
854 int error; 860 int error;
@@ -865,6 +871,7 @@ static int nfs4_init_client(struct nfs_client *clp,
865 error = nfs_create_rpc_client(clp, proto, timeo, retrans, authflavour); 871 error = nfs_create_rpc_client(clp, proto, timeo, retrans, authflavour);
866 if (error < 0) 872 if (error < 0)
867 goto error; 873 goto error;
874 memcpy(clp->cl_ipaddr, ip_addr, sizeof(clp->cl_ipaddr));
868 875
869 error = nfs_idmap_new(clp); 876 error = nfs_idmap_new(clp);
870 if (error < 0) { 877 if (error < 0) {
@@ -888,6 +895,7 @@ error:
888 */ 895 */
889static int nfs4_set_client(struct nfs_server *server, 896static int nfs4_set_client(struct nfs_server *server,
890 const char *hostname, const struct sockaddr_in *addr, 897 const char *hostname, const struct sockaddr_in *addr,
898 const char *ip_addr,
891 rpc_authflavor_t authflavour, 899 rpc_authflavor_t authflavour,
892 int proto, int timeo, int retrans) 900 int proto, int timeo, int retrans)
893{ 901{
@@ -902,7 +910,7 @@ static int nfs4_set_client(struct nfs_server *server,
902 error = PTR_ERR(clp); 910 error = PTR_ERR(clp);
903 goto error; 911 goto error;
904 } 912 }
905 error = nfs4_init_client(clp, proto, timeo, retrans, authflavour); 913 error = nfs4_init_client(clp, proto, timeo, retrans, ip_addr, authflavour);
906 if (error < 0) 914 if (error < 0)
907 goto error_put; 915 goto error_put;
908 916
@@ -971,7 +979,7 @@ struct nfs_server *nfs4_create_server(const struct nfs4_mount_data *data,
971 return ERR_PTR(-ENOMEM); 979 return ERR_PTR(-ENOMEM);
972 980
973 /* Get a client record */ 981 /* Get a client record */
974 error = nfs4_set_client(server, hostname, addr, authflavour, 982 error = nfs4_set_client(server, hostname, addr, ip_addr, authflavour,
975 data->proto, data->timeo, data->retrans); 983 data->proto, data->timeo, data->retrans);
976 if (error < 0) 984 if (error < 0)
977 goto error; 985 goto error;
@@ -1041,6 +1049,7 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data,
1041 /* Get a client representation. 1049 /* Get a client representation.
1042 * Note: NFSv4 always uses TCP, */ 1050 * Note: NFSv4 always uses TCP, */
1043 error = nfs4_set_client(server, data->hostname, data->addr, 1051 error = nfs4_set_client(server, data->hostname, data->addr,
1052 parent_client->cl_ipaddr,
1044 data->authflavor, 1053 data->authflavor,
1045 parent_server->client->cl_xprt->prot, 1054 parent_server->client->cl_xprt->prot,
1046 parent_client->retrans_timeo, 1055 parent_client->retrans_timeo,