diff options
Diffstat (limited to 'fs/nfs')
-rw-r--r-- | fs/nfs/client.c | 41 |
1 files changed, 39 insertions, 2 deletions
diff --git a/fs/nfs/client.c b/fs/nfs/client.c index 701cd193a014..876162cddf1e 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c | |||
@@ -34,6 +34,8 @@ | |||
34 | #include <linux/nfs_idmap.h> | 34 | #include <linux/nfs_idmap.h> |
35 | #include <linux/vfs.h> | 35 | #include <linux/vfs.h> |
36 | #include <linux/inet.h> | 36 | #include <linux/inet.h> |
37 | #include <linux/in6.h> | ||
38 | #include <net/ipv6.h> | ||
37 | #include <linux/nfs_xdr.h> | 39 | #include <linux/nfs_xdr.h> |
38 | 40 | ||
39 | #include <asm/system.h> | 41 | #include <asm/system.h> |
@@ -208,16 +210,44 @@ void nfs_put_client(struct nfs_client *clp) | |||
208 | } | 210 | } |
209 | } | 211 | } |
210 | 212 | ||
213 | static int nfs_sockaddr_match_ipaddr4(const struct sockaddr_in *sa1, | ||
214 | const struct sockaddr_in *sa2) | ||
215 | { | ||
216 | return sa1->sin_addr.s_addr == sa2->sin_addr.s_addr; | ||
217 | } | ||
218 | |||
219 | static int nfs_sockaddr_match_ipaddr6(const struct sockaddr_in6 *sa1, | ||
220 | const struct sockaddr_in6 *sa2) | ||
221 | { | ||
222 | return ipv6_addr_equal(&sa1->sin6_addr, &sa2->sin6_addr); | ||
223 | } | ||
224 | |||
225 | static int nfs_sockaddr_match_ipaddr(const struct sockaddr *sa1, | ||
226 | const struct sockaddr *sa2) | ||
227 | { | ||
228 | switch (sa1->sa_family) { | ||
229 | case AF_INET: | ||
230 | return nfs_sockaddr_match_ipaddr4((const struct sockaddr_in *)sa1, | ||
231 | (const struct sockaddr_in *)sa2); | ||
232 | case AF_INET6: | ||
233 | return nfs_sockaddr_match_ipaddr6((const struct sockaddr_in6 *)sa1, | ||
234 | (const struct sockaddr_in6 *)sa2); | ||
235 | } | ||
236 | BUG(); | ||
237 | } | ||
238 | |||
211 | /* | 239 | /* |
212 | * Find a client by IP address and protocol version | 240 | * Find a client by IP address and protocol version |
213 | * - returns NULL if no such client | 241 | * - returns NULL if no such client |
214 | */ | 242 | */ |
215 | struct nfs_client *nfs_find_client(const struct sockaddr_in *addr, int nfsversion) | 243 | struct nfs_client *_nfs_find_client(const struct sockaddr *addr, int nfsversion) |
216 | { | 244 | { |
217 | struct nfs_client *clp; | 245 | struct nfs_client *clp; |
218 | 246 | ||
219 | spin_lock(&nfs_client_lock); | 247 | spin_lock(&nfs_client_lock); |
220 | list_for_each_entry(clp, &nfs_client_list, cl_share_link) { | 248 | list_for_each_entry(clp, &nfs_client_list, cl_share_link) { |
249 | struct sockaddr *clap = (struct sockaddr *)&clp->cl_addr; | ||
250 | |||
221 | /* Don't match clients that failed to initialise properly */ | 251 | /* Don't match clients that failed to initialise properly */ |
222 | if (clp->cl_cons_state != NFS_CS_READY) | 252 | if (clp->cl_cons_state != NFS_CS_READY) |
223 | continue; | 253 | continue; |
@@ -226,8 +256,10 @@ struct nfs_client *nfs_find_client(const struct sockaddr_in *addr, int nfsversio | |||
226 | if (clp->rpc_ops->version != nfsversion) | 256 | if (clp->rpc_ops->version != nfsversion) |
227 | continue; | 257 | continue; |
228 | 258 | ||
259 | if (addr->sa_family != clap->sa_family) | ||
260 | continue; | ||
229 | /* Match only the IP address, not the port number */ | 261 | /* Match only the IP address, not the port number */ |
230 | if (clp->cl_addr.sin_addr.s_addr != addr->sin_addr.s_addr) | 262 | if (!nfs_sockaddr_match_ipaddr(addr, clap)) |
231 | continue; | 263 | continue; |
232 | 264 | ||
233 | atomic_inc(&clp->cl_count); | 265 | atomic_inc(&clp->cl_count); |
@@ -238,6 +270,11 @@ struct nfs_client *nfs_find_client(const struct sockaddr_in *addr, int nfsversio | |||
238 | return NULL; | 270 | return NULL; |
239 | } | 271 | } |
240 | 272 | ||
273 | struct nfs_client *nfs_find_client(const struct sockaddr_in *addr, int nfsversion) | ||
274 | { | ||
275 | return _nfs_find_client((const struct sockaddr *)addr, nfsversion); | ||
276 | } | ||
277 | |||
241 | /* | 278 | /* |
242 | * Find an nfs_client on the list that matches the initialisation data | 279 | * Find an nfs_client on the list that matches the initialisation data |
243 | * that is supplied. | 280 | * that is supplied. |