diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-24 14:45:00 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-24 14:45:00 -0400 |
commit | 10c993a6b5418cb1026775765ba4c70ffb70853d (patch) | |
tree | 717deba79b938c2f3f786ff6fe908d30582f06f8 /fs/lockd | |
parent | c328d54cd4ad120d76284e46dcca6c6cf996154a (diff) | |
parent | ca456252db0521e5e88024fa2b67535e9739e030 (diff) |
Merge branch 'for-linus' of git://linux-nfs.org/~bfields/linux
* 'for-linus' of git://linux-nfs.org/~bfields/linux: (52 commits)
knfsd: clear both setuid and setgid whenever a chown is done
knfsd: get rid of imode variable in nfsd_setattr
SUNRPC: Use unsigned loop and array index in svc_init_buffer()
SUNRPC: Use unsigned index when looping over arrays
SUNRPC: Update RPC server's TCP record marker decoder
SUNRPC: RPC server still uses 2.4 method for disabling TCP Nagle
NLM: don't let lockd exit on unexpected svc_recv errors (try #2)
NFS: don't let nfs_callback_svc exit on unexpected svc_recv errors (try #2)
Use a zero sized array for raw field in struct fid
nfsd: use static memory for callback program and stats
SUNRPC: remove svc_create_thread()
nfsd: fix comment
lockd: Fix stale nlmsvc_unlink_block comment
NFSD: Strip __KERNEL__ testing from unexported header files.
sunrpc: make token header values less confusing
gss_krb5: consistently use unsigned for seqnum
NFSD: Remove NFSv4 dependency on NFSv3
SUNRPC: Remove PROC_FS dependency
NFSD: Use "depends on" for PROC_FS dependency
nfsd: move most of fh_verify to separate function
...
Diffstat (limited to 'fs/lockd')
-rw-r--r-- | fs/lockd/host.c | 73 | ||||
-rw-r--r-- | fs/lockd/svc.c | 150 | ||||
-rw-r--r-- | fs/lockd/svclock.c | 6 | ||||
-rw-r--r-- | fs/lockd/svcshare.c | 3 |
4 files changed, 111 insertions, 121 deletions
diff --git a/fs/lockd/host.c b/fs/lockd/host.c index f1ef49fff118..c7854791898f 100644 --- a/fs/lockd/host.c +++ b/fs/lockd/host.c | |||
@@ -19,12 +19,11 @@ | |||
19 | 19 | ||
20 | 20 | ||
21 | #define NLMDBG_FACILITY NLMDBG_HOSTCACHE | 21 | #define NLMDBG_FACILITY NLMDBG_HOSTCACHE |
22 | #define NLM_HOST_MAX 64 | ||
23 | #define NLM_HOST_NRHASH 32 | 22 | #define NLM_HOST_NRHASH 32 |
24 | #define NLM_ADDRHASH(addr) (ntohl(addr) & (NLM_HOST_NRHASH-1)) | 23 | #define NLM_ADDRHASH(addr) (ntohl(addr) & (NLM_HOST_NRHASH-1)) |
25 | #define NLM_HOST_REBIND (60 * HZ) | 24 | #define NLM_HOST_REBIND (60 * HZ) |
26 | #define NLM_HOST_EXPIRE ((nrhosts > NLM_HOST_MAX)? 300 * HZ : 120 * HZ) | 25 | #define NLM_HOST_EXPIRE (300 * HZ) |
27 | #define NLM_HOST_COLLECT ((nrhosts > NLM_HOST_MAX)? 120 * HZ : 60 * HZ) | 26 | #define NLM_HOST_COLLECT (120 * HZ) |
28 | 27 | ||
29 | static struct hlist_head nlm_hosts[NLM_HOST_NRHASH]; | 28 | static struct hlist_head nlm_hosts[NLM_HOST_NRHASH]; |
30 | static unsigned long next_gc; | 29 | static unsigned long next_gc; |
@@ -142,9 +141,7 @@ nlm_lookup_host(int server, const struct sockaddr_in *sin, | |||
142 | INIT_LIST_HEAD(&host->h_granted); | 141 | INIT_LIST_HEAD(&host->h_granted); |
143 | INIT_LIST_HEAD(&host->h_reclaim); | 142 | INIT_LIST_HEAD(&host->h_reclaim); |
144 | 143 | ||
145 | if (++nrhosts > NLM_HOST_MAX) | 144 | nrhosts++; |
146 | next_gc = 0; | ||
147 | |||
148 | out: | 145 | out: |
149 | mutex_unlock(&nlm_host_mutex); | 146 | mutex_unlock(&nlm_host_mutex); |
150 | return host; | 147 | return host; |
@@ -460,7 +457,7 @@ nlm_gc_hosts(void) | |||
460 | * Manage NSM handles | 457 | * Manage NSM handles |
461 | */ | 458 | */ |
462 | static LIST_HEAD(nsm_handles); | 459 | static LIST_HEAD(nsm_handles); |
463 | static DEFINE_MUTEX(nsm_mutex); | 460 | static DEFINE_SPINLOCK(nsm_lock); |
464 | 461 | ||
465 | static struct nsm_handle * | 462 | static struct nsm_handle * |
466 | __nsm_find(const struct sockaddr_in *sin, | 463 | __nsm_find(const struct sockaddr_in *sin, |
@@ -468,7 +465,7 @@ __nsm_find(const struct sockaddr_in *sin, | |||
468 | int create) | 465 | int create) |
469 | { | 466 | { |
470 | struct nsm_handle *nsm = NULL; | 467 | struct nsm_handle *nsm = NULL; |
471 | struct list_head *pos; | 468 | struct nsm_handle *pos; |
472 | 469 | ||
473 | if (!sin) | 470 | if (!sin) |
474 | return NULL; | 471 | return NULL; |
@@ -482,38 +479,43 @@ __nsm_find(const struct sockaddr_in *sin, | |||
482 | return NULL; | 479 | return NULL; |
483 | } | 480 | } |
484 | 481 | ||
485 | mutex_lock(&nsm_mutex); | 482 | retry: |
486 | list_for_each(pos, &nsm_handles) { | 483 | spin_lock(&nsm_lock); |
487 | nsm = list_entry(pos, struct nsm_handle, sm_link); | 484 | list_for_each_entry(pos, &nsm_handles, sm_link) { |
488 | 485 | ||
489 | if (hostname && nsm_use_hostnames) { | 486 | if (hostname && nsm_use_hostnames) { |
490 | if (strlen(nsm->sm_name) != hostname_len | 487 | if (strlen(pos->sm_name) != hostname_len |
491 | || memcmp(nsm->sm_name, hostname, hostname_len)) | 488 | || memcmp(pos->sm_name, hostname, hostname_len)) |
492 | continue; | 489 | continue; |
493 | } else if (!nlm_cmp_addr(&nsm->sm_addr, sin)) | 490 | } else if (!nlm_cmp_addr(&pos->sm_addr, sin)) |
494 | continue; | 491 | continue; |
495 | atomic_inc(&nsm->sm_count); | 492 | atomic_inc(&pos->sm_count); |
496 | goto out; | 493 | kfree(nsm); |
494 | nsm = pos; | ||
495 | goto found; | ||
497 | } | 496 | } |
498 | 497 | if (nsm) { | |
499 | if (!create) { | 498 | list_add(&nsm->sm_link, &nsm_handles); |
500 | nsm = NULL; | 499 | goto found; |
501 | goto out; | ||
502 | } | 500 | } |
501 | spin_unlock(&nsm_lock); | ||
502 | |||
503 | if (!create) | ||
504 | return NULL; | ||
503 | 505 | ||
504 | nsm = kzalloc(sizeof(*nsm) + hostname_len + 1, GFP_KERNEL); | 506 | nsm = kzalloc(sizeof(*nsm) + hostname_len + 1, GFP_KERNEL); |
505 | if (nsm != NULL) { | 507 | if (nsm == NULL) |
506 | nsm->sm_addr = *sin; | 508 | return NULL; |
507 | nsm->sm_name = (char *) (nsm + 1); | ||
508 | memcpy(nsm->sm_name, hostname, hostname_len); | ||
509 | nsm->sm_name[hostname_len] = '\0'; | ||
510 | atomic_set(&nsm->sm_count, 1); | ||
511 | 509 | ||
512 | list_add(&nsm->sm_link, &nsm_handles); | 510 | nsm->sm_addr = *sin; |
513 | } | 511 | nsm->sm_name = (char *) (nsm + 1); |
512 | memcpy(nsm->sm_name, hostname, hostname_len); | ||
513 | nsm->sm_name[hostname_len] = '\0'; | ||
514 | atomic_set(&nsm->sm_count, 1); | ||
515 | goto retry; | ||
514 | 516 | ||
515 | out: | 517 | found: |
516 | mutex_unlock(&nsm_mutex); | 518 | spin_unlock(&nsm_lock); |
517 | return nsm; | 519 | return nsm; |
518 | } | 520 | } |
519 | 521 | ||
@@ -532,12 +534,9 @@ nsm_release(struct nsm_handle *nsm) | |||
532 | { | 534 | { |
533 | if (!nsm) | 535 | if (!nsm) |
534 | return; | 536 | return; |
535 | if (atomic_dec_and_test(&nsm->sm_count)) { | 537 | if (atomic_dec_and_lock(&nsm->sm_count, &nsm_lock)) { |
536 | mutex_lock(&nsm_mutex); | 538 | list_del(&nsm->sm_link); |
537 | if (atomic_read(&nsm->sm_count) == 0) { | 539 | spin_unlock(&nsm_lock); |
538 | list_del(&nsm->sm_link); | 540 | kfree(nsm); |
539 | kfree(nsm); | ||
540 | } | ||
541 | mutex_unlock(&nsm_mutex); | ||
542 | } | 541 | } |
543 | } | 542 | } |
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c index 1ed8bd4de941..cf977bbcf303 100644 --- a/fs/lockd/svc.c +++ b/fs/lockd/svc.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/smp.h> | 25 | #include <linux/smp.h> |
26 | #include <linux/smp_lock.h> | 26 | #include <linux/smp_lock.h> |
27 | #include <linux/mutex.h> | 27 | #include <linux/mutex.h> |
28 | #include <linux/kthread.h> | ||
28 | #include <linux/freezer.h> | 29 | #include <linux/freezer.h> |
29 | 30 | ||
30 | #include <linux/sunrpc/types.h> | 31 | #include <linux/sunrpc/types.h> |
@@ -48,14 +49,11 @@ EXPORT_SYMBOL(nlmsvc_ops); | |||
48 | 49 | ||
49 | static DEFINE_MUTEX(nlmsvc_mutex); | 50 | static DEFINE_MUTEX(nlmsvc_mutex); |
50 | static unsigned int nlmsvc_users; | 51 | static unsigned int nlmsvc_users; |
51 | static pid_t nlmsvc_pid; | 52 | static struct task_struct *nlmsvc_task; |
52 | static struct svc_serv *nlmsvc_serv; | 53 | static struct svc_serv *nlmsvc_serv; |
53 | int nlmsvc_grace_period; | 54 | int nlmsvc_grace_period; |
54 | unsigned long nlmsvc_timeout; | 55 | unsigned long nlmsvc_timeout; |
55 | 56 | ||
56 | static DECLARE_COMPLETION(lockd_start_done); | ||
57 | static DECLARE_WAIT_QUEUE_HEAD(lockd_exit); | ||
58 | |||
59 | /* | 57 | /* |
60 | * These can be set at insmod time (useful for NFS as root filesystem), | 58 | * These can be set at insmod time (useful for NFS as root filesystem), |
61 | * and also changed through the sysctl interface. -- Jamie Lokier, Aug 2003 | 59 | * and also changed through the sysctl interface. -- Jamie Lokier, Aug 2003 |
@@ -111,35 +109,30 @@ static inline void clear_grace_period(void) | |||
111 | /* | 109 | /* |
112 | * This is the lockd kernel thread | 110 | * This is the lockd kernel thread |
113 | */ | 111 | */ |
114 | static void | 112 | static int |
115 | lockd(struct svc_rqst *rqstp) | 113 | lockd(void *vrqstp) |
116 | { | 114 | { |
117 | int err = 0; | 115 | int err = 0, preverr = 0; |
116 | struct svc_rqst *rqstp = vrqstp; | ||
118 | unsigned long grace_period_expire; | 117 | unsigned long grace_period_expire; |
119 | 118 | ||
120 | /* Lock module and set up kernel thread */ | 119 | /* try_to_freeze() is called from svc_recv() */ |
121 | /* lockd_up is waiting for us to startup, so will | ||
122 | * be holding a reference to this module, so it | ||
123 | * is safe to just claim another reference | ||
124 | */ | ||
125 | __module_get(THIS_MODULE); | ||
126 | lock_kernel(); | ||
127 | |||
128 | /* | ||
129 | * Let our maker know we're running. | ||
130 | */ | ||
131 | nlmsvc_pid = current->pid; | ||
132 | nlmsvc_serv = rqstp->rq_server; | ||
133 | complete(&lockd_start_done); | ||
134 | |||
135 | daemonize("lockd"); | ||
136 | set_freezable(); | 120 | set_freezable(); |
137 | 121 | ||
138 | /* Process request with signals blocked, but allow SIGKILL. */ | 122 | /* Allow SIGKILL to tell lockd to drop all of its locks */ |
139 | allow_signal(SIGKILL); | 123 | allow_signal(SIGKILL); |
140 | 124 | ||
141 | dprintk("NFS locking service started (ver " LOCKD_VERSION ").\n"); | 125 | dprintk("NFS locking service started (ver " LOCKD_VERSION ").\n"); |
142 | 126 | ||
127 | /* | ||
128 | * FIXME: it would be nice if lockd didn't spend its entire life | ||
129 | * running under the BKL. At the very least, it would be good to | ||
130 | * have someone clarify what it's intended to protect here. I've | ||
131 | * seen some handwavy posts about posix locking needing to be | ||
132 | * done under the BKL, but it's far from clear. | ||
133 | */ | ||
134 | lock_kernel(); | ||
135 | |||
143 | if (!nlm_timeout) | 136 | if (!nlm_timeout) |
144 | nlm_timeout = LOCKD_DFLT_TIMEO; | 137 | nlm_timeout = LOCKD_DFLT_TIMEO; |
145 | nlmsvc_timeout = nlm_timeout * HZ; | 138 | nlmsvc_timeout = nlm_timeout * HZ; |
@@ -148,10 +141,9 @@ lockd(struct svc_rqst *rqstp) | |||
148 | 141 | ||
149 | /* | 142 | /* |
150 | * The main request loop. We don't terminate until the last | 143 | * The main request loop. We don't terminate until the last |
151 | * NFS mount or NFS daemon has gone away, and we've been sent a | 144 | * NFS mount or NFS daemon has gone away. |
152 | * signal, or else another process has taken over our job. | ||
153 | */ | 145 | */ |
154 | while ((nlmsvc_users || !signalled()) && nlmsvc_pid == current->pid) { | 146 | while (!kthread_should_stop()) { |
155 | long timeout = MAX_SCHEDULE_TIMEOUT; | 147 | long timeout = MAX_SCHEDULE_TIMEOUT; |
156 | RPC_IFDEBUG(char buf[RPC_MAX_ADDRBUFLEN]); | 148 | RPC_IFDEBUG(char buf[RPC_MAX_ADDRBUFLEN]); |
157 | 149 | ||
@@ -161,6 +153,7 @@ lockd(struct svc_rqst *rqstp) | |||
161 | nlmsvc_invalidate_all(); | 153 | nlmsvc_invalidate_all(); |
162 | grace_period_expire = set_grace_period(); | 154 | grace_period_expire = set_grace_period(); |
163 | } | 155 | } |
156 | continue; | ||
164 | } | 157 | } |
165 | 158 | ||
166 | /* | 159 | /* |
@@ -179,14 +172,20 @@ lockd(struct svc_rqst *rqstp) | |||
179 | * recvfrom routine. | 172 | * recvfrom routine. |
180 | */ | 173 | */ |
181 | err = svc_recv(rqstp, timeout); | 174 | err = svc_recv(rqstp, timeout); |
182 | if (err == -EAGAIN || err == -EINTR) | 175 | if (err == -EAGAIN || err == -EINTR) { |
176 | preverr = err; | ||
183 | continue; | 177 | continue; |
178 | } | ||
184 | if (err < 0) { | 179 | if (err < 0) { |
185 | printk(KERN_WARNING | 180 | if (err != preverr) { |
186 | "lockd: terminating on error %d\n", | 181 | printk(KERN_WARNING "%s: unexpected error " |
187 | -err); | 182 | "from svc_recv (%d)\n", __func__, err); |
188 | break; | 183 | preverr = err; |
184 | } | ||
185 | schedule_timeout_interruptible(HZ); | ||
186 | continue; | ||
189 | } | 187 | } |
188 | preverr = err; | ||
190 | 189 | ||
191 | dprintk("lockd: request from %s\n", | 190 | dprintk("lockd: request from %s\n", |
192 | svc_print_addr(rqstp, buf, sizeof(buf))); | 191 | svc_print_addr(rqstp, buf, sizeof(buf))); |
@@ -195,28 +194,19 @@ lockd(struct svc_rqst *rqstp) | |||
195 | } | 194 | } |
196 | 195 | ||
197 | flush_signals(current); | 196 | flush_signals(current); |
197 | if (nlmsvc_ops) | ||
198 | nlmsvc_invalidate_all(); | ||
199 | nlm_shutdown_hosts(); | ||
198 | 200 | ||
199 | /* | 201 | unlock_kernel(); |
200 | * Check whether there's a new lockd process before | 202 | |
201 | * shutting down the hosts and clearing the slot. | 203 | nlmsvc_task = NULL; |
202 | */ | 204 | nlmsvc_serv = NULL; |
203 | if (!nlmsvc_pid || current->pid == nlmsvc_pid) { | ||
204 | if (nlmsvc_ops) | ||
205 | nlmsvc_invalidate_all(); | ||
206 | nlm_shutdown_hosts(); | ||
207 | nlmsvc_pid = 0; | ||
208 | nlmsvc_serv = NULL; | ||
209 | } else | ||
210 | printk(KERN_DEBUG | ||
211 | "lockd: new process, skipping host shutdown\n"); | ||
212 | wake_up(&lockd_exit); | ||
213 | 205 | ||
214 | /* Exit the RPC thread */ | 206 | /* Exit the RPC thread */ |
215 | svc_exit_thread(rqstp); | 207 | svc_exit_thread(rqstp); |
216 | 208 | ||
217 | /* Release module */ | 209 | return 0; |
218 | unlock_kernel(); | ||
219 | module_put_and_exit(0); | ||
220 | } | 210 | } |
221 | 211 | ||
222 | /* | 212 | /* |
@@ -261,14 +251,15 @@ static int make_socks(struct svc_serv *serv, int proto) | |||
261 | int | 251 | int |
262 | lockd_up(int proto) /* Maybe add a 'family' option when IPv6 is supported ?? */ | 252 | lockd_up(int proto) /* Maybe add a 'family' option when IPv6 is supported ?? */ |
263 | { | 253 | { |
264 | struct svc_serv * serv; | 254 | struct svc_serv *serv; |
265 | int error = 0; | 255 | struct svc_rqst *rqstp; |
256 | int error = 0; | ||
266 | 257 | ||
267 | mutex_lock(&nlmsvc_mutex); | 258 | mutex_lock(&nlmsvc_mutex); |
268 | /* | 259 | /* |
269 | * Check whether we're already up and running. | 260 | * Check whether we're already up and running. |
270 | */ | 261 | */ |
271 | if (nlmsvc_pid) { | 262 | if (nlmsvc_serv) { |
272 | if (proto) | 263 | if (proto) |
273 | error = make_socks(nlmsvc_serv, proto); | 264 | error = make_socks(nlmsvc_serv, proto); |
274 | goto out; | 265 | goto out; |
@@ -295,13 +286,28 @@ lockd_up(int proto) /* Maybe add a 'family' option when IPv6 is supported ?? */ | |||
295 | /* | 286 | /* |
296 | * Create the kernel thread and wait for it to start. | 287 | * Create the kernel thread and wait for it to start. |
297 | */ | 288 | */ |
298 | error = svc_create_thread(lockd, serv); | 289 | rqstp = svc_prepare_thread(serv, &serv->sv_pools[0]); |
299 | if (error) { | 290 | if (IS_ERR(rqstp)) { |
291 | error = PTR_ERR(rqstp); | ||
292 | printk(KERN_WARNING | ||
293 | "lockd_up: svc_rqst allocation failed, error=%d\n", | ||
294 | error); | ||
295 | goto destroy_and_out; | ||
296 | } | ||
297 | |||
298 | svc_sock_update_bufs(serv); | ||
299 | nlmsvc_serv = rqstp->rq_server; | ||
300 | |||
301 | nlmsvc_task = kthread_run(lockd, rqstp, serv->sv_name); | ||
302 | if (IS_ERR(nlmsvc_task)) { | ||
303 | error = PTR_ERR(nlmsvc_task); | ||
304 | nlmsvc_task = NULL; | ||
305 | nlmsvc_serv = NULL; | ||
300 | printk(KERN_WARNING | 306 | printk(KERN_WARNING |
301 | "lockd_up: create thread failed, error=%d\n", error); | 307 | "lockd_up: kthread_run failed, error=%d\n", error); |
308 | svc_exit_thread(rqstp); | ||
302 | goto destroy_and_out; | 309 | goto destroy_and_out; |
303 | } | 310 | } |
304 | wait_for_completion(&lockd_start_done); | ||
305 | 311 | ||
306 | /* | 312 | /* |
307 | * Note: svc_serv structures have an initial use count of 1, | 313 | * Note: svc_serv structures have an initial use count of 1, |
@@ -323,37 +329,21 @@ EXPORT_SYMBOL(lockd_up); | |||
323 | void | 329 | void |
324 | lockd_down(void) | 330 | lockd_down(void) |
325 | { | 331 | { |
326 | static int warned; | ||
327 | |||
328 | mutex_lock(&nlmsvc_mutex); | 332 | mutex_lock(&nlmsvc_mutex); |
329 | if (nlmsvc_users) { | 333 | if (nlmsvc_users) { |
330 | if (--nlmsvc_users) | 334 | if (--nlmsvc_users) |
331 | goto out; | 335 | goto out; |
332 | } else | 336 | } else { |
333 | printk(KERN_WARNING "lockd_down: no users! pid=%d\n", nlmsvc_pid); | 337 | printk(KERN_ERR "lockd_down: no users! task=%p\n", |
334 | 338 | nlmsvc_task); | |
335 | if (!nlmsvc_pid) { | 339 | BUG(); |
336 | if (warned++ == 0) | ||
337 | printk(KERN_WARNING "lockd_down: no lockd running.\n"); | ||
338 | goto out; | ||
339 | } | 340 | } |
340 | warned = 0; | ||
341 | 341 | ||
342 | kill_proc(nlmsvc_pid, SIGKILL, 1); | 342 | if (!nlmsvc_task) { |
343 | /* | 343 | printk(KERN_ERR "lockd_down: no lockd running.\n"); |
344 | * Wait for the lockd process to exit, but since we're holding | 344 | BUG(); |
345 | * the lockd semaphore, we can't wait around forever ... | ||
346 | */ | ||
347 | clear_thread_flag(TIF_SIGPENDING); | ||
348 | interruptible_sleep_on_timeout(&lockd_exit, HZ); | ||
349 | if (nlmsvc_pid) { | ||
350 | printk(KERN_WARNING | ||
351 | "lockd_down: lockd failed to exit, clearing pid\n"); | ||
352 | nlmsvc_pid = 0; | ||
353 | } | 345 | } |
354 | spin_lock_irq(¤t->sighand->siglock); | 346 | kthread_stop(nlmsvc_task); |
355 | recalc_sigpending(); | ||
356 | spin_unlock_irq(¤t->sighand->siglock); | ||
357 | out: | 347 | out: |
358 | mutex_unlock(&nlmsvc_mutex); | 348 | mutex_unlock(&nlmsvc_mutex); |
359 | } | 349 | } |
diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c index fe9bdb4a220c..1f122c1940af 100644 --- a/fs/lockd/svclock.c +++ b/fs/lockd/svclock.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/sunrpc/svc.h> | 29 | #include <linux/sunrpc/svc.h> |
30 | #include <linux/lockd/nlm.h> | 30 | #include <linux/lockd/nlm.h> |
31 | #include <linux/lockd/lockd.h> | 31 | #include <linux/lockd/lockd.h> |
32 | #include <linux/kthread.h> | ||
32 | 33 | ||
33 | #define NLMDBG_FACILITY NLMDBG_SVCLOCK | 34 | #define NLMDBG_FACILITY NLMDBG_SVCLOCK |
34 | 35 | ||
@@ -226,8 +227,7 @@ failed: | |||
226 | } | 227 | } |
227 | 228 | ||
228 | /* | 229 | /* |
229 | * Delete a block. If the lock was cancelled or the grant callback | 230 | * Delete a block. |
230 | * failed, unlock is set to 1. | ||
231 | * It is the caller's responsibility to check whether the file | 231 | * It is the caller's responsibility to check whether the file |
232 | * can be closed hereafter. | 232 | * can be closed hereafter. |
233 | */ | 233 | */ |
@@ -887,7 +887,7 @@ nlmsvc_retry_blocked(void) | |||
887 | unsigned long timeout = MAX_SCHEDULE_TIMEOUT; | 887 | unsigned long timeout = MAX_SCHEDULE_TIMEOUT; |
888 | struct nlm_block *block; | 888 | struct nlm_block *block; |
889 | 889 | ||
890 | while (!list_empty(&nlm_blocked)) { | 890 | while (!list_empty(&nlm_blocked) && !kthread_should_stop()) { |
891 | block = list_entry(nlm_blocked.next, struct nlm_block, b_list); | 891 | block = list_entry(nlm_blocked.next, struct nlm_block, b_list); |
892 | 892 | ||
893 | if (block->b_when == NLM_NEVER) | 893 | if (block->b_when == NLM_NEVER) |
diff --git a/fs/lockd/svcshare.c b/fs/lockd/svcshare.c index 068886de4dda..b0ae07008700 100644 --- a/fs/lockd/svcshare.c +++ b/fs/lockd/svcshare.c | |||
@@ -71,7 +71,8 @@ nlmsvc_unshare_file(struct nlm_host *host, struct nlm_file *file, | |||
71 | struct nlm_share *share, **shpp; | 71 | struct nlm_share *share, **shpp; |
72 | struct xdr_netobj *oh = &argp->lock.oh; | 72 | struct xdr_netobj *oh = &argp->lock.oh; |
73 | 73 | ||
74 | for (shpp = &file->f_shares; (share = *shpp) != 0; shpp = &share->s_next) { | 74 | for (shpp = &file->f_shares; (share = *shpp) != NULL; |
75 | shpp = &share->s_next) { | ||
75 | if (share->s_host == host && nlm_cmp_owner(share, oh)) { | 76 | if (share->s_host == host && nlm_cmp_owner(share, oh)) { |
76 | *shpp = share->s_next; | 77 | *shpp = share->s_next; |
77 | kfree(share); | 78 | kfree(share); |