diff options
Diffstat (limited to 'fs/lockd/host.c')
-rw-r--r-- | fs/lockd/host.c | 39 |
1 files changed, 22 insertions, 17 deletions
diff --git a/fs/lockd/host.c b/fs/lockd/host.c index 96070bff93fc..572601e98dcd 100644 --- a/fs/lockd/host.c +++ b/fs/lockd/host.c | |||
@@ -44,9 +44,8 @@ static struct nsm_handle * nsm_find(const struct sockaddr_in *sin, | |||
44 | */ | 44 | */ |
45 | static struct nlm_host * | 45 | static struct nlm_host * |
46 | nlm_lookup_host(int server, const struct sockaddr_in *sin, | 46 | nlm_lookup_host(int server, const struct sockaddr_in *sin, |
47 | int proto, int version, | 47 | int proto, int version, const char *hostname, |
48 | const char *hostname, | 48 | int hostname_len, const struct sockaddr_in *ssin) |
49 | int hostname_len) | ||
50 | { | 49 | { |
51 | struct hlist_head *chain; | 50 | struct hlist_head *chain; |
52 | struct hlist_node *pos; | 51 | struct hlist_node *pos; |
@@ -54,7 +53,9 @@ nlm_lookup_host(int server, const struct sockaddr_in *sin, | |||
54 | struct nsm_handle *nsm = NULL; | 53 | struct nsm_handle *nsm = NULL; |
55 | int hash; | 54 | int hash; |
56 | 55 | ||
57 | dprintk("lockd: nlm_lookup_host(%u.%u.%u.%u, p=%d, v=%d, my role=%s, name=%.*s)\n", | 56 | dprintk("lockd: nlm_lookup_host("NIPQUAD_FMT"->"NIPQUAD_FMT |
57 | ", p=%d, v=%d, my role=%s, name=%.*s)\n", | ||
58 | NIPQUAD(ssin->sin_addr.s_addr), | ||
58 | NIPQUAD(sin->sin_addr.s_addr), proto, version, | 59 | NIPQUAD(sin->sin_addr.s_addr), proto, version, |
59 | server? "server" : "client", | 60 | server? "server" : "client", |
60 | hostname_len, | 61 | hostname_len, |
@@ -91,6 +92,8 @@ nlm_lookup_host(int server, const struct sockaddr_in *sin, | |||
91 | continue; | 92 | continue; |
92 | if (host->h_server != server) | 93 | if (host->h_server != server) |
93 | continue; | 94 | continue; |
95 | if (!nlm_cmp_addr(&host->h_saddr, ssin)) | ||
96 | continue; | ||
94 | 97 | ||
95 | /* Move to head of hash chain. */ | 98 | /* Move to head of hash chain. */ |
96 | hlist_del(&host->h_hash); | 99 | hlist_del(&host->h_hash); |
@@ -118,6 +121,7 @@ nlm_lookup_host(int server, const struct sockaddr_in *sin, | |||
118 | host->h_name = nsm->sm_name; | 121 | host->h_name = nsm->sm_name; |
119 | host->h_addr = *sin; | 122 | host->h_addr = *sin; |
120 | host->h_addr.sin_port = 0; /* ouch! */ | 123 | host->h_addr.sin_port = 0; /* ouch! */ |
124 | host->h_saddr = *ssin; | ||
121 | host->h_version = version; | 125 | host->h_version = version; |
122 | host->h_proto = proto; | 126 | host->h_proto = proto; |
123 | host->h_rpcclnt = NULL; | 127 | host->h_rpcclnt = NULL; |
@@ -161,15 +165,9 @@ nlm_destroy_host(struct nlm_host *host) | |||
161 | */ | 165 | */ |
162 | nsm_unmonitor(host); | 166 | nsm_unmonitor(host); |
163 | 167 | ||
164 | if ((clnt = host->h_rpcclnt) != NULL) { | 168 | clnt = host->h_rpcclnt; |
165 | if (atomic_read(&clnt->cl_users)) { | 169 | if (clnt != NULL) |
166 | printk(KERN_WARNING | 170 | rpc_shutdown_client(clnt); |
167 | "lockd: active RPC handle\n"); | ||
168 | clnt->cl_dead = 1; | ||
169 | } else { | ||
170 | rpc_destroy_client(host->h_rpcclnt); | ||
171 | } | ||
172 | } | ||
173 | kfree(host); | 171 | kfree(host); |
174 | } | 172 | } |
175 | 173 | ||
@@ -180,8 +178,10 @@ struct nlm_host * | |||
180 | nlmclnt_lookup_host(const struct sockaddr_in *sin, int proto, int version, | 178 | nlmclnt_lookup_host(const struct sockaddr_in *sin, int proto, int version, |
181 | const char *hostname, int hostname_len) | 179 | const char *hostname, int hostname_len) |
182 | { | 180 | { |
181 | struct sockaddr_in ssin = {0}; | ||
182 | |||
183 | return nlm_lookup_host(0, sin, proto, version, | 183 | return nlm_lookup_host(0, sin, proto, version, |
184 | hostname, hostname_len); | 184 | hostname, hostname_len, &ssin); |
185 | } | 185 | } |
186 | 186 | ||
187 | /* | 187 | /* |
@@ -191,9 +191,12 @@ struct nlm_host * | |||
191 | nlmsvc_lookup_host(struct svc_rqst *rqstp, | 191 | nlmsvc_lookup_host(struct svc_rqst *rqstp, |
192 | const char *hostname, int hostname_len) | 192 | const char *hostname, int hostname_len) |
193 | { | 193 | { |
194 | struct sockaddr_in ssin = {0}; | ||
195 | |||
196 | ssin.sin_addr = rqstp->rq_daddr.addr; | ||
194 | return nlm_lookup_host(1, svc_addr_in(rqstp), | 197 | return nlm_lookup_host(1, svc_addr_in(rqstp), |
195 | rqstp->rq_prot, rqstp->rq_vers, | 198 | rqstp->rq_prot, rqstp->rq_vers, |
196 | hostname, hostname_len); | 199 | hostname, hostname_len, &ssin); |
197 | } | 200 | } |
198 | 201 | ||
199 | /* | 202 | /* |
@@ -204,8 +207,9 @@ nlm_bind_host(struct nlm_host *host) | |||
204 | { | 207 | { |
205 | struct rpc_clnt *clnt; | 208 | struct rpc_clnt *clnt; |
206 | 209 | ||
207 | dprintk("lockd: nlm_bind_host(%08x)\n", | 210 | dprintk("lockd: nlm_bind_host("NIPQUAD_FMT"->"NIPQUAD_FMT")\n", |
208 | (unsigned)ntohl(host->h_addr.sin_addr.s_addr)); | 211 | NIPQUAD(host->h_saddr.sin_addr), |
212 | NIPQUAD(host->h_addr.sin_addr)); | ||
209 | 213 | ||
210 | /* Lock host handle */ | 214 | /* Lock host handle */ |
211 | mutex_lock(&host->h_mutex); | 215 | mutex_lock(&host->h_mutex); |
@@ -232,6 +236,7 @@ nlm_bind_host(struct nlm_host *host) | |||
232 | .protocol = host->h_proto, | 236 | .protocol = host->h_proto, |
233 | .address = (struct sockaddr *)&host->h_addr, | 237 | .address = (struct sockaddr *)&host->h_addr, |
234 | .addrsize = sizeof(host->h_addr), | 238 | .addrsize = sizeof(host->h_addr), |
239 | .saddress = (struct sockaddr *)&host->h_saddr, | ||
235 | .timeout = &timeparms, | 240 | .timeout = &timeparms, |
236 | .servername = host->h_name, | 241 | .servername = host->h_name, |
237 | .program = &nlm_program, | 242 | .program = &nlm_program, |