aboutsummaryrefslogtreecommitdiffstats
path: root/fs/lockd/host.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/lockd/host.c')
-rw-r--r--fs/lockd/host.c31
1 files changed, 19 insertions, 12 deletions
diff --git a/fs/lockd/host.c b/fs/lockd/host.c
index 82f7a0b1d8ae..729ac427d359 100644
--- a/fs/lockd/host.c
+++ b/fs/lockd/host.c
@@ -16,6 +16,7 @@
16#include <linux/sunrpc/svc.h> 16#include <linux/sunrpc/svc.h>
17#include <linux/lockd/lockd.h> 17#include <linux/lockd/lockd.h>
18#include <linux/lockd/sm_inter.h> 18#include <linux/lockd/sm_inter.h>
19#include <linux/mutex.h>
19 20
20 21
21#define NLMDBG_FACILITY NLMDBG_HOSTCACHE 22#define NLMDBG_FACILITY NLMDBG_HOSTCACHE
@@ -30,7 +31,7 @@
30static struct nlm_host * nlm_hosts[NLM_HOST_NRHASH]; 31static struct nlm_host * nlm_hosts[NLM_HOST_NRHASH];
31static unsigned long next_gc; 32static unsigned long next_gc;
32static int nrhosts; 33static int nrhosts;
33static DECLARE_MUTEX(nlm_host_sema); 34static DEFINE_MUTEX(nlm_host_mutex);
34 35
35 36
36static void nlm_gc_hosts(void); 37static void nlm_gc_hosts(void);
@@ -71,7 +72,7 @@ nlm_lookup_host(int server, struct sockaddr_in *sin,
71 hash = NLM_ADDRHASH(sin->sin_addr.s_addr); 72 hash = NLM_ADDRHASH(sin->sin_addr.s_addr);
72 73
73 /* Lock hash table */ 74 /* Lock hash table */
74 down(&nlm_host_sema); 75 mutex_lock(&nlm_host_mutex);
75 76
76 if (time_after_eq(jiffies, next_gc)) 77 if (time_after_eq(jiffies, next_gc))
77 nlm_gc_hosts(); 78 nlm_gc_hosts();
@@ -91,7 +92,7 @@ nlm_lookup_host(int server, struct sockaddr_in *sin,
91 nlm_hosts[hash] = host; 92 nlm_hosts[hash] = host;
92 } 93 }
93 nlm_get_host(host); 94 nlm_get_host(host);
94 up(&nlm_host_sema); 95 mutex_unlock(&nlm_host_mutex);
95 return host; 96 return host;
96 } 97 }
97 } 98 }
@@ -123,12 +124,14 @@ nlm_lookup_host(int server, struct sockaddr_in *sin,
123 nlm_hosts[hash] = host; 124 nlm_hosts[hash] = host;
124 INIT_LIST_HEAD(&host->h_lockowners); 125 INIT_LIST_HEAD(&host->h_lockowners);
125 spin_lock_init(&host->h_lock); 126 spin_lock_init(&host->h_lock);
127 INIT_LIST_HEAD(&host->h_granted);
128 INIT_LIST_HEAD(&host->h_reclaim);
126 129
127 if (++nrhosts > NLM_HOST_MAX) 130 if (++nrhosts > NLM_HOST_MAX)
128 next_gc = 0; 131 next_gc = 0;
129 132
130nohost: 133nohost:
131 up(&nlm_host_sema); 134 mutex_unlock(&nlm_host_mutex);
132 return host; 135 return host;
133} 136}
134 137
@@ -139,19 +142,19 @@ nlm_find_client(void)
139 * and return it 142 * and return it
140 */ 143 */
141 int hash; 144 int hash;
142 down(&nlm_host_sema); 145 mutex_lock(&nlm_host_mutex);
143 for (hash = 0 ; hash < NLM_HOST_NRHASH; hash++) { 146 for (hash = 0 ; hash < NLM_HOST_NRHASH; hash++) {
144 struct nlm_host *host, **hp; 147 struct nlm_host *host, **hp;
145 for (hp = &nlm_hosts[hash]; (host = *hp) != 0; hp = &host->h_next) { 148 for (hp = &nlm_hosts[hash]; (host = *hp) != 0; hp = &host->h_next) {
146 if (host->h_server && 149 if (host->h_server &&
147 host->h_killed == 0) { 150 host->h_killed == 0) {
148 nlm_get_host(host); 151 nlm_get_host(host);
149 up(&nlm_host_sema); 152 mutex_unlock(&nlm_host_mutex);
150 return host; 153 return host;
151 } 154 }
152 } 155 }
153 } 156 }
154 up(&nlm_host_sema); 157 mutex_unlock(&nlm_host_mutex);
155 return NULL; 158 return NULL;
156} 159}
157 160
@@ -191,11 +194,12 @@ nlm_bind_host(struct nlm_host *host)
191 xprt->resvport = 1; /* NLM requires a reserved port */ 194 xprt->resvport = 1; /* NLM requires a reserved port */
192 195
193 /* Existing NLM servers accept AUTH_UNIX only */ 196 /* Existing NLM servers accept AUTH_UNIX only */
194 clnt = rpc_create_client(xprt, host->h_name, &nlm_program, 197 clnt = rpc_new_client(xprt, host->h_name, &nlm_program,
195 host->h_version, RPC_AUTH_UNIX); 198 host->h_version, RPC_AUTH_UNIX);
196 if (IS_ERR(clnt)) 199 if (IS_ERR(clnt))
197 goto forgetit; 200 goto forgetit;
198 clnt->cl_autobind = 1; /* turn on pmap queries */ 201 clnt->cl_autobind = 1; /* turn on pmap queries */
202 clnt->cl_softrtry = 1; /* All queries are soft */
199 203
200 host->h_rpcclnt = clnt; 204 host->h_rpcclnt = clnt;
201 } 205 }
@@ -242,8 +246,12 @@ void nlm_release_host(struct nlm_host *host)
242{ 246{
243 if (host != NULL) { 247 if (host != NULL) {
244 dprintk("lockd: release host %s\n", host->h_name); 248 dprintk("lockd: release host %s\n", host->h_name);
245 atomic_dec(&host->h_count);
246 BUG_ON(atomic_read(&host->h_count) < 0); 249 BUG_ON(atomic_read(&host->h_count) < 0);
250 if (atomic_dec_and_test(&host->h_count)) {
251 BUG_ON(!list_empty(&host->h_lockowners));
252 BUG_ON(!list_empty(&host->h_granted));
253 BUG_ON(!list_empty(&host->h_reclaim));
254 }
247 } 255 }
248} 256}
249 257
@@ -258,7 +266,7 @@ nlm_shutdown_hosts(void)
258 int i; 266 int i;
259 267
260 dprintk("lockd: shutting down host module\n"); 268 dprintk("lockd: shutting down host module\n");
261 down(&nlm_host_sema); 269 mutex_lock(&nlm_host_mutex);
262 270
263 /* First, make all hosts eligible for gc */ 271 /* First, make all hosts eligible for gc */
264 dprintk("lockd: nuking all hosts...\n"); 272 dprintk("lockd: nuking all hosts...\n");
@@ -269,7 +277,7 @@ nlm_shutdown_hosts(void)
269 277
270 /* Then, perform a garbage collection pass */ 278 /* Then, perform a garbage collection pass */
271 nlm_gc_hosts(); 279 nlm_gc_hosts();
272 up(&nlm_host_sema); 280 mutex_unlock(&nlm_host_mutex);
273 281
274 /* complain if any hosts are left */ 282 /* complain if any hosts are left */
275 if (nrhosts) { 283 if (nrhosts) {
@@ -331,7 +339,6 @@ nlm_gc_hosts(void)
331 rpc_destroy_client(host->h_rpcclnt); 339 rpc_destroy_client(host->h_rpcclnt);
332 } 340 }
333 } 341 }
334 BUG_ON(!list_empty(&host->h_lockowners));
335 kfree(host); 342 kfree(host);
336 nrhosts--; 343 nrhosts--;
337 } 344 }