diff options
Diffstat (limited to 'fs/nfs/client.c')
-rw-r--r-- | fs/nfs/client.c | 52 |
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 | */ |
214 | static struct nfs_client *__nfs_find_client(const struct sockaddr_in *addr, int nfsversion, int match_port) | 214 | struct 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 | |||
236 | found: | ||
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 | */ |
245 | struct nfs_client *nfs_find_client(const struct sockaddr_in *addr, int nfsversion) | 244 | static 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) |