diff options
| -rw-r--r-- | fs/lockd/host.c | 47 | ||||
| -rw-r--r-- | include/linux/lockd/lockd.h | 5 |
2 files changed, 41 insertions, 11 deletions
diff --git a/fs/lockd/host.c b/fs/lockd/host.c index cbd2398e594c..9fd8889097b7 100644 --- a/fs/lockd/host.c +++ b/fs/lockd/host.c | |||
| @@ -304,16 +304,33 @@ struct nlm_host *nlmclnt_lookup_host(const struct sockaddr *sap, | |||
| 304 | return nlm_lookup_host(&ni); | 304 | return nlm_lookup_host(&ni); |
| 305 | } | 305 | } |
| 306 | 306 | ||
| 307 | /* | 307 | /** |
| 308 | * Find an NLM client handle in the cache. If there is none, create it. | 308 | * nlmsvc_lookup_host - Find an NLM host handle matching a remote client |
| 309 | * @rqstp: incoming NLM request | ||
| 310 | * @hostname: name of client host | ||
| 311 | * @hostname_len: length of client hostname | ||
| 312 | * | ||
| 313 | * Returns an nlm_host structure that matches the [client address, | ||
| 314 | * transport protocol, NLM version, client hostname] of the passed-in | ||
| 315 | * NLM request. If one doesn't already exist in the host cache, a | ||
| 316 | * new handle is created and returned. | ||
| 317 | * | ||
| 318 | * Before possibly creating a new nlm_host, construct a sockaddr | ||
| 319 | * for a specific source address in case the local system has | ||
| 320 | * multiple network addresses. The family of the address in | ||
| 321 | * rq_daddr is guaranteed to be the same as the family of the | ||
| 322 | * address in rq_addr, so it's safe to use the same family for | ||
| 323 | * the source address. | ||
| 309 | */ | 324 | */ |
| 310 | struct nlm_host * | 325 | struct nlm_host *nlmsvc_lookup_host(const struct svc_rqst *rqstp, |
| 311 | nlmsvc_lookup_host(struct svc_rqst *rqstp, | 326 | const char *hostname, |
| 312 | const char *hostname, unsigned int hostname_len) | 327 | const size_t hostname_len) |
| 313 | { | 328 | { |
| 314 | const struct sockaddr_in source = { | 329 | struct sockaddr_in sin = { |
| 315 | .sin_family = AF_INET, | 330 | .sin_family = AF_INET, |
| 316 | .sin_addr = rqstp->rq_daddr.addr, | 331 | }; |
| 332 | struct sockaddr_in6 sin6 = { | ||
| 333 | .sin6_family = AF_INET6, | ||
| 317 | }; | 334 | }; |
| 318 | struct nlm_lookup_host_info ni = { | 335 | struct nlm_lookup_host_info ni = { |
| 319 | .server = 1, | 336 | .server = 1, |
| @@ -323,14 +340,26 @@ nlmsvc_lookup_host(struct svc_rqst *rqstp, | |||
| 323 | .version = rqstp->rq_vers, | 340 | .version = rqstp->rq_vers, |
| 324 | .hostname = hostname, | 341 | .hostname = hostname, |
| 325 | .hostname_len = hostname_len, | 342 | .hostname_len = hostname_len, |
| 326 | .src_sap = (struct sockaddr *)&source, | 343 | .src_len = rqstp->rq_addrlen, |
| 327 | .src_len = sizeof(source), | ||
| 328 | }; | 344 | }; |
| 329 | 345 | ||
| 330 | dprintk("lockd: %s(host='%*s', vers=%u, proto=%s)\n", __func__, | 346 | dprintk("lockd: %s(host='%*s', vers=%u, proto=%s)\n", __func__, |
| 331 | (int)hostname_len, hostname, rqstp->rq_vers, | 347 | (int)hostname_len, hostname, rqstp->rq_vers, |
| 332 | (rqstp->rq_prot == IPPROTO_UDP ? "udp" : "tcp")); | 348 | (rqstp->rq_prot == IPPROTO_UDP ? "udp" : "tcp")); |
| 333 | 349 | ||
| 350 | switch (ni.sap->sa_family) { | ||
| 351 | case AF_INET: | ||
| 352 | sin.sin_addr.s_addr = rqstp->rq_daddr.addr.s_addr; | ||
| 353 | ni.src_sap = (struct sockaddr *)&sin; | ||
| 354 | break; | ||
| 355 | case AF_INET6: | ||
| 356 | ipv6_addr_copy(&sin6.sin6_addr, &rqstp->rq_daddr.addr6); | ||
| 357 | ni.src_sap = (struct sockaddr *)&sin6; | ||
| 358 | break; | ||
| 359 | default: | ||
| 360 | return NULL; | ||
| 361 | } | ||
| 362 | |||
| 334 | return nlm_lookup_host(&ni); | 363 | return nlm_lookup_host(&ni); |
| 335 | } | 364 | } |
| 336 | 365 | ||
diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h index 90a996d2f005..16ff2e88f05d 100644 --- a/include/linux/lockd/lockd.h +++ b/include/linux/lockd/lockd.h | |||
| @@ -220,8 +220,9 @@ struct nlm_host *nlmclnt_lookup_host(const struct sockaddr *sap, | |||
| 220 | const unsigned short protocol, | 220 | const unsigned short protocol, |
| 221 | const u32 version, | 221 | const u32 version, |
| 222 | const char *hostname); | 222 | const char *hostname); |
| 223 | struct nlm_host *nlmsvc_lookup_host(struct svc_rqst *, const char *, | 223 | struct nlm_host *nlmsvc_lookup_host(const struct svc_rqst *rqstp, |
| 224 | unsigned int); | 224 | const char *hostname, |
| 225 | const size_t hostname_len); | ||
| 225 | struct rpc_clnt * nlm_bind_host(struct nlm_host *); | 226 | struct rpc_clnt * nlm_bind_host(struct nlm_host *); |
| 226 | void nlm_rebind_host(struct nlm_host *); | 227 | void nlm_rebind_host(struct nlm_host *); |
| 227 | struct nlm_host * nlm_get_host(struct nlm_host *); | 228 | struct nlm_host * nlm_get_host(struct nlm_host *); |
