X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;ds=sidebyside;f=fs%2Flockd%2Fhost.c;h=ca6b16fc3101a3df88d60350060eae56d6528535;hb=b7e23d913aafc93fc5f119e1be17620073cc3811;hp=ad21c0713efa705ad7aeb5a18f165a46a934453f;hpb=42eaf0d8f2e7b8201afc00b0ebe1bd89ea51d42d;p=linux-2.6-omap-h63xx.git diff --git a/fs/lockd/host.c b/fs/lockd/host.c index ad21c0713ef..ca6b16fc310 100644 --- a/fs/lockd/host.c +++ b/fs/lockd/host.c @@ -34,19 +34,19 @@ static DEFINE_MUTEX(nlm_host_mutex); static void nlm_gc_hosts(void); static struct nsm_handle * __nsm_find(const struct sockaddr_in *, - const char *, int, int); + const char *, unsigned int, int); static struct nsm_handle * nsm_find(const struct sockaddr_in *sin, const char *hostname, - int hostname_len); + unsigned int hostname_len); /* * Common host lookup routine for server & client */ static struct nlm_host * nlm_lookup_host(int server, const struct sockaddr_in *sin, - int proto, int version, - const char *hostname, - int hostname_len) + int proto, int version, const char *hostname, + unsigned int hostname_len, + const struct sockaddr_in *ssin) { struct hlist_head *chain; struct hlist_node *pos; @@ -54,7 +54,9 @@ nlm_lookup_host(int server, const struct sockaddr_in *sin, struct nsm_handle *nsm = NULL; int hash; - dprintk("lockd: nlm_lookup_host(%u.%u.%u.%u, p=%d, v=%d, my role=%s, name=%.*s)\n", + dprintk("lockd: nlm_lookup_host("NIPQUAD_FMT"->"NIPQUAD_FMT + ", p=%d, v=%d, my role=%s, name=%.*s)\n", + NIPQUAD(ssin->sin_addr.s_addr), NIPQUAD(sin->sin_addr.s_addr), proto, version, server? "server" : "client", hostname_len, @@ -91,6 +93,8 @@ nlm_lookup_host(int server, const struct sockaddr_in *sin, continue; if (host->h_server != server) continue; + if (!nlm_cmp_addr(&host->h_saddr, ssin)) + continue; /* Move to head of hash chain. */ hlist_del(&host->h_hash); @@ -118,6 +122,7 @@ nlm_lookup_host(int server, const struct sockaddr_in *sin, host->h_name = nsm->sm_name; host->h_addr = *sin; host->h_addr.sin_port = 0; /* ouch! */ + host->h_saddr = *ssin; host->h_version = version; host->h_proto = proto; host->h_rpcclnt = NULL; @@ -161,15 +166,9 @@ nlm_destroy_host(struct nlm_host *host) */ nsm_unmonitor(host); - if ((clnt = host->h_rpcclnt) != NULL) { - if (atomic_read(&clnt->cl_users)) { - printk(KERN_WARNING - "lockd: active RPC handle\n"); - clnt->cl_dead = 1; - } else { - rpc_destroy_client(host->h_rpcclnt); - } - } + clnt = host->h_rpcclnt; + if (clnt != NULL) + rpc_shutdown_client(clnt); kfree(host); } @@ -178,10 +177,12 @@ nlm_destroy_host(struct nlm_host *host) */ struct nlm_host * nlmclnt_lookup_host(const struct sockaddr_in *sin, int proto, int version, - const char *hostname, int hostname_len) + const char *hostname, unsigned int hostname_len) { + struct sockaddr_in ssin = {0}; + return nlm_lookup_host(0, sin, proto, version, - hostname, hostname_len); + hostname, hostname_len, &ssin); } /* @@ -189,11 +190,14 @@ nlmclnt_lookup_host(const struct sockaddr_in *sin, int proto, int version, */ struct nlm_host * nlmsvc_lookup_host(struct svc_rqst *rqstp, - const char *hostname, int hostname_len) + const char *hostname, unsigned int hostname_len) { + struct sockaddr_in ssin = {0}; + + ssin.sin_addr = rqstp->rq_daddr.addr; return nlm_lookup_host(1, svc_addr_in(rqstp), rqstp->rq_prot, rqstp->rq_vers, - hostname, hostname_len); + hostname, hostname_len, &ssin); } /* @@ -204,8 +208,9 @@ nlm_bind_host(struct nlm_host *host) { struct rpc_clnt *clnt; - dprintk("lockd: nlm_bind_host(%08x)\n", - (unsigned)ntohl(host->h_addr.sin_addr.s_addr)); + dprintk("lockd: nlm_bind_host("NIPQUAD_FMT"->"NIPQUAD_FMT")\n", + NIPQUAD(host->h_saddr.sin_addr), + NIPQUAD(host->h_addr.sin_addr)); /* Lock host handle */ mutex_lock(&host->h_mutex); @@ -221,7 +226,7 @@ nlm_bind_host(struct nlm_host *host) host->h_nextrebind - jiffies); } } else { - unsigned long increment = nlmsvc_timeout * HZ; + unsigned long increment = nlmsvc_timeout; struct rpc_timeout timeparms = { .to_initval = increment, .to_increment = increment, @@ -232,6 +237,7 @@ nlm_bind_host(struct nlm_host *host) .protocol = host->h_proto, .address = (struct sockaddr *)&host->h_addr, .addrsize = sizeof(host->h_addr), + .saddress = (struct sockaddr *)&host->h_saddr, .timeout = &timeparms, .servername = host->h_name, .program = &nlm_program, @@ -302,7 +308,8 @@ void nlm_release_host(struct nlm_host *host) * Release all resources held by that peer. */ void nlm_host_rebooted(const struct sockaddr_in *sin, - const char *hostname, int hostname_len, + const char *hostname, + unsigned int hostname_len, u32 new_state) { struct hlist_head *chain; @@ -372,8 +379,13 @@ nlm_shutdown_hosts(void) /* First, make all hosts eligible for gc */ dprintk("lockd: nuking all hosts...\n"); for (chain = nlm_hosts; chain < nlm_hosts + NLM_HOST_NRHASH; ++chain) { - hlist_for_each_entry(host, pos, chain, h_hash) + hlist_for_each_entry(host, pos, chain, h_hash) { host->h_expires = jiffies - 1; + if (host->h_rpcclnt) { + rpc_shutdown_client(host->h_rpcclnt); + host->h_rpcclnt = NULL; + } + } } /* Then, perform a garbage collection pass */ @@ -444,7 +456,7 @@ static DEFINE_MUTEX(nsm_mutex); static struct nsm_handle * __nsm_find(const struct sockaddr_in *sin, - const char *hostname, int hostname_len, + const char *hostname, unsigned int hostname_len, int create) { struct nsm_handle *nsm = NULL; @@ -498,7 +510,8 @@ out: } static struct nsm_handle * -nsm_find(const struct sockaddr_in *sin, const char *hostname, int hostname_len) +nsm_find(const struct sockaddr_in *sin, const char *hostname, + unsigned int hostname_len) { return __nsm_find(sin, hostname, hostname_len, 1); }