diff options
Diffstat (limited to 'fs/lockd/host.c')
-rw-r--r-- | fs/lockd/host.c | 31 |
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 @@ | |||
30 | static struct nlm_host * nlm_hosts[NLM_HOST_NRHASH]; | 31 | static struct nlm_host * nlm_hosts[NLM_HOST_NRHASH]; |
31 | static unsigned long next_gc; | 32 | static unsigned long next_gc; |
32 | static int nrhosts; | 33 | static int nrhosts; |
33 | static DECLARE_MUTEX(nlm_host_sema); | 34 | static DEFINE_MUTEX(nlm_host_mutex); |
34 | 35 | ||
35 | 36 | ||
36 | static void nlm_gc_hosts(void); | 37 | static 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 | ||
130 | nohost: | 133 | nohost: |
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 | } |