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.c52
1 files changed, 30 insertions, 22 deletions
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index d7f6d50442b7..ff778ecee0bd 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -208,52 +208,60 @@ void nfs_put_client(struct nfs_client *clp)
208} 208}
209 209
210/* 210/*
211 * Find a client by address 211 * Find a client by IP address and protocol version
212 * - caller must hold nfs_client_lock 212 * - returns NULL if no such client
213 */ 213 */
214static struct nfs_client *__nfs_find_client(const struct sockaddr_in *addr, int nfsversion, int match_port) 214struct nfs_client *nfs_find_client(const struct sockaddr_in *addr, int nfsversion)
215{ 215{
216 struct nfs_client *clp; 216 struct nfs_client *clp;
217 217
218 spin_lock(&nfs_client_lock);
218 list_for_each_entry(clp, &nfs_client_list, cl_share_link) { 219 list_for_each_entry(clp, &nfs_client_list, cl_share_link) {
219 /* Don't match clients that failed to initialise properly */ 220 /* Don't match clients that failed to initialise properly */
220 if (clp->cl_cons_state < 0) 221 if (clp->cl_cons_state != NFS_CS_READY)
221 continue; 222 continue;
222 223
223 /* Different NFS versions cannot share the same nfs_client */ 224 /* Different NFS versions cannot share the same nfs_client */
224 if (clp->cl_nfsversion != nfsversion) 225 if (clp->cl_nfsversion != nfsversion)
225 continue; 226 continue;
226 227
228 /* Match only the IP address, not the port number */
227 if (clp->cl_addr.sin_addr.s_addr != addr->sin_addr.s_addr) 229 if (clp->cl_addr.sin_addr.s_addr != addr->sin_addr.s_addr)
228 continue; 230 continue;
229 231
230 if (!match_port || clp->cl_addr.sin_port == addr->sin_port) 232 atomic_inc(&clp->cl_count);
231 goto found; 233 spin_unlock(&nfs_client_lock);
234 return clp;
232 } 235 }
233 236 spin_unlock(&nfs_client_lock);
234 return NULL; 237 return NULL;
235
236found:
237 atomic_inc(&clp->cl_count);
238 return clp;
239} 238}
240 239
241/* 240/*
242 * Find a client by IP address and protocol version 241 * Find an nfs_client on the list that matches the initialisation data
243 * - returns NULL if no such client 242 * that is supplied.
244 */ 243 */
245struct nfs_client *nfs_find_client(const struct sockaddr_in *addr, int nfsversion) 244static struct nfs_client *nfs_match_client(const struct nfs_client_initdata *data)
246{ 245{
247 struct nfs_client *clp; 246 struct nfs_client *clp;
248 247
249 spin_lock(&nfs_client_lock); 248 list_for_each_entry(clp, &nfs_client_list, cl_share_link) {
250 clp = __nfs_find_client(addr, nfsversion, 0); 249 /* Don't match clients that failed to initialise properly */
251 spin_unlock(&nfs_client_lock); 250 if (clp->cl_cons_state < 0)
252 if (clp != NULL && clp->cl_cons_state != NFS_CS_READY) { 251 continue;
253 nfs_put_client(clp); 252
254 clp = NULL; 253 /* Different NFS versions cannot share the same nfs_client */
254 if (clp->cl_nfsversion != data->version)
255 continue;
256
257 /* Match the full socket address */
258 if (memcmp(&clp->cl_addr, data->addr, sizeof(clp->cl_addr)) != 0)
259 continue;
260
261 atomic_inc(&clp->cl_count);
262 return clp;
255 } 263 }
256 return clp; 264 return NULL;
257} 265}
258 266
259/* 267/*
@@ -273,7 +281,7 @@ static struct nfs_client *nfs_get_client(const struct nfs_client_initdata *cl_in
273 do { 281 do {
274 spin_lock(&nfs_client_lock); 282 spin_lock(&nfs_client_lock);
275 283
276 clp = __nfs_find_client(cl_init->addr, cl_init->version, 1); 284 clp = nfs_match_client(cl_init);
277 if (clp) 285 if (clp)
278 goto found_client; 286 goto found_client;
279 if (new) 287 if (new)