diff options
Diffstat (limited to 'fs/lockd')
| -rw-r--r-- | fs/lockd/clntlock.c | 15 | ||||
| -rw-r--r-- | fs/lockd/clntproc.c | 13 | ||||
| -rw-r--r-- | fs/lockd/host.c | 1 | ||||
| -rw-r--r-- | fs/lockd/mon.c | 1 | ||||
| -rw-r--r-- | fs/lockd/svc.c | 13 | ||||
| -rw-r--r-- | fs/lockd/svc4proc.c | 2 | ||||
| -rw-r--r-- | fs/lockd/svclock.c | 37 | ||||
| -rw-r--r-- | fs/lockd/svcproc.c | 2 | ||||
| -rw-r--r-- | fs/lockd/svcsubs.c | 9 |
9 files changed, 50 insertions, 43 deletions
diff --git a/fs/lockd/clntlock.c b/fs/lockd/clntlock.c index 64fd427c993..d5bb86866e6 100644 --- a/fs/lockd/clntlock.c +++ b/fs/lockd/clntlock.c | |||
| @@ -42,6 +42,7 @@ struct nlm_wait { | |||
| 42 | }; | 42 | }; |
| 43 | 43 | ||
| 44 | static LIST_HEAD(nlm_blocked); | 44 | static LIST_HEAD(nlm_blocked); |
| 45 | static DEFINE_SPINLOCK(nlm_blocked_lock); | ||
| 45 | 46 | ||
| 46 | /** | 47 | /** |
| 47 | * nlmclnt_init - Set up per-NFS mount point lockd data structures | 48 | * nlmclnt_init - Set up per-NFS mount point lockd data structures |
| @@ -97,7 +98,10 @@ struct nlm_wait *nlmclnt_prepare_block(struct nlm_host *host, struct file_lock * | |||
| 97 | block->b_lock = fl; | 98 | block->b_lock = fl; |
| 98 | init_waitqueue_head(&block->b_wait); | 99 | init_waitqueue_head(&block->b_wait); |
| 99 | block->b_status = nlm_lck_blocked; | 100 | block->b_status = nlm_lck_blocked; |
| 101 | |||
| 102 | spin_lock(&nlm_blocked_lock); | ||
| 100 | list_add(&block->b_list, &nlm_blocked); | 103 | list_add(&block->b_list, &nlm_blocked); |
| 104 | spin_unlock(&nlm_blocked_lock); | ||
| 101 | } | 105 | } |
| 102 | return block; | 106 | return block; |
| 103 | } | 107 | } |
| @@ -106,7 +110,9 @@ void nlmclnt_finish_block(struct nlm_wait *block) | |||
| 106 | { | 110 | { |
| 107 | if (block == NULL) | 111 | if (block == NULL) |
| 108 | return; | 112 | return; |
| 113 | spin_lock(&nlm_blocked_lock); | ||
| 109 | list_del(&block->b_list); | 114 | list_del(&block->b_list); |
| 115 | spin_unlock(&nlm_blocked_lock); | ||
| 110 | kfree(block); | 116 | kfree(block); |
| 111 | } | 117 | } |
| 112 | 118 | ||
| @@ -154,6 +160,7 @@ __be32 nlmclnt_grant(const struct sockaddr *addr, const struct nlm_lock *lock) | |||
| 154 | * Look up blocked request based on arguments. | 160 | * Look up blocked request based on arguments. |
| 155 | * Warning: must not use cookie to match it! | 161 | * Warning: must not use cookie to match it! |
| 156 | */ | 162 | */ |
| 163 | spin_lock(&nlm_blocked_lock); | ||
| 157 | list_for_each_entry(block, &nlm_blocked, b_list) { | 164 | list_for_each_entry(block, &nlm_blocked, b_list) { |
| 158 | struct file_lock *fl_blocked = block->b_lock; | 165 | struct file_lock *fl_blocked = block->b_lock; |
| 159 | 166 | ||
| @@ -178,6 +185,7 @@ __be32 nlmclnt_grant(const struct sockaddr *addr, const struct nlm_lock *lock) | |||
| 178 | wake_up(&block->b_wait); | 185 | wake_up(&block->b_wait); |
| 179 | res = nlm_granted; | 186 | res = nlm_granted; |
| 180 | } | 187 | } |
| 188 | spin_unlock(&nlm_blocked_lock); | ||
| 181 | return res; | 189 | return res; |
| 182 | } | 190 | } |
| 183 | 191 | ||
| @@ -216,10 +224,6 @@ reclaimer(void *ptr) | |||
| 216 | allow_signal(SIGKILL); | 224 | allow_signal(SIGKILL); |
| 217 | 225 | ||
| 218 | down_write(&host->h_rwsem); | 226 | down_write(&host->h_rwsem); |
| 219 | |||
| 220 | /* This one ensures that our parent doesn't terminate while the | ||
| 221 | * reclaim is in progress */ | ||
| 222 | lock_kernel(); | ||
| 223 | lockd_up(); /* note: this cannot fail as lockd is already running */ | 227 | lockd_up(); /* note: this cannot fail as lockd is already running */ |
| 224 | 228 | ||
| 225 | dprintk("lockd: reclaiming locks for host %s\n", host->h_name); | 229 | dprintk("lockd: reclaiming locks for host %s\n", host->h_name); |
| @@ -260,16 +264,17 @@ restart: | |||
| 260 | dprintk("NLM: done reclaiming locks for host %s\n", host->h_name); | 264 | dprintk("NLM: done reclaiming locks for host %s\n", host->h_name); |
| 261 | 265 | ||
| 262 | /* Now, wake up all processes that sleep on a blocked lock */ | 266 | /* Now, wake up all processes that sleep on a blocked lock */ |
| 267 | spin_lock(&nlm_blocked_lock); | ||
| 263 | list_for_each_entry(block, &nlm_blocked, b_list) { | 268 | list_for_each_entry(block, &nlm_blocked, b_list) { |
| 264 | if (block->b_host == host) { | 269 | if (block->b_host == host) { |
| 265 | block->b_status = nlm_lck_denied_grace_period; | 270 | block->b_status = nlm_lck_denied_grace_period; |
| 266 | wake_up(&block->b_wait); | 271 | wake_up(&block->b_wait); |
| 267 | } | 272 | } |
| 268 | } | 273 | } |
| 274 | spin_unlock(&nlm_blocked_lock); | ||
| 269 | 275 | ||
| 270 | /* Release host handle after use */ | 276 | /* Release host handle after use */ |
| 271 | nlm_release_host(host); | 277 | nlm_release_host(host); |
| 272 | lockd_down(); | 278 | lockd_down(); |
| 273 | unlock_kernel(); | ||
| 274 | return 0; | 279 | return 0; |
| 275 | } | 280 | } |
diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c index 7932c399fab..47ea1e1925b 100644 --- a/fs/lockd/clntproc.c +++ b/fs/lockd/clntproc.c | |||
| @@ -166,7 +166,6 @@ int nlmclnt_proc(struct nlm_host *host, int cmd, struct file_lock *fl) | |||
| 166 | /* Set up the argument struct */ | 166 | /* Set up the argument struct */ |
| 167 | nlmclnt_setlockargs(call, fl); | 167 | nlmclnt_setlockargs(call, fl); |
| 168 | 168 | ||
| 169 | lock_kernel(); | ||
| 170 | if (IS_SETLK(cmd) || IS_SETLKW(cmd)) { | 169 | if (IS_SETLK(cmd) || IS_SETLKW(cmd)) { |
| 171 | if (fl->fl_type != F_UNLCK) { | 170 | if (fl->fl_type != F_UNLCK) { |
| 172 | call->a_args.block = IS_SETLKW(cmd) ? 1 : 0; | 171 | call->a_args.block = IS_SETLKW(cmd) ? 1 : 0; |
| @@ -177,10 +176,8 @@ int nlmclnt_proc(struct nlm_host *host, int cmd, struct file_lock *fl) | |||
| 177 | status = nlmclnt_test(call, fl); | 176 | status = nlmclnt_test(call, fl); |
| 178 | else | 177 | else |
| 179 | status = -EINVAL; | 178 | status = -EINVAL; |
| 180 | |||
| 181 | fl->fl_ops->fl_release_private(fl); | 179 | fl->fl_ops->fl_release_private(fl); |
| 182 | fl->fl_ops = NULL; | 180 | fl->fl_ops = NULL; |
| 183 | unlock_kernel(); | ||
| 184 | 181 | ||
| 185 | dprintk("lockd: clnt proc returns %d\n", status); | 182 | dprintk("lockd: clnt proc returns %d\n", status); |
| 186 | return status; | 183 | return status; |
| @@ -226,9 +223,7 @@ void nlm_release_call(struct nlm_rqst *call) | |||
| 226 | 223 | ||
| 227 | static void nlmclnt_rpc_release(void *data) | 224 | static void nlmclnt_rpc_release(void *data) |
| 228 | { | 225 | { |
| 229 | lock_kernel(); | ||
| 230 | nlm_release_call(data); | 226 | nlm_release_call(data); |
| 231 | unlock_kernel(); | ||
| 232 | } | 227 | } |
| 233 | 228 | ||
| 234 | static int nlm_wait_on_grace(wait_queue_head_t *queue) | 229 | static int nlm_wait_on_grace(wait_queue_head_t *queue) |
| @@ -448,14 +443,18 @@ out: | |||
| 448 | 443 | ||
| 449 | static void nlmclnt_locks_copy_lock(struct file_lock *new, struct file_lock *fl) | 444 | static void nlmclnt_locks_copy_lock(struct file_lock *new, struct file_lock *fl) |
| 450 | { | 445 | { |
| 446 | spin_lock(&fl->fl_u.nfs_fl.owner->host->h_lock); | ||
| 451 | new->fl_u.nfs_fl.state = fl->fl_u.nfs_fl.state; | 447 | new->fl_u.nfs_fl.state = fl->fl_u.nfs_fl.state; |
| 452 | new->fl_u.nfs_fl.owner = nlm_get_lockowner(fl->fl_u.nfs_fl.owner); | 448 | new->fl_u.nfs_fl.owner = nlm_get_lockowner(fl->fl_u.nfs_fl.owner); |
| 453 | list_add_tail(&new->fl_u.nfs_fl.list, &fl->fl_u.nfs_fl.owner->host->h_granted); | 449 | list_add_tail(&new->fl_u.nfs_fl.list, &fl->fl_u.nfs_fl.owner->host->h_granted); |
| 450 | spin_unlock(&fl->fl_u.nfs_fl.owner->host->h_lock); | ||
| 454 | } | 451 | } |
| 455 | 452 | ||
| 456 | static void nlmclnt_locks_release_private(struct file_lock *fl) | 453 | static void nlmclnt_locks_release_private(struct file_lock *fl) |
| 457 | { | 454 | { |
| 455 | spin_lock(&fl->fl_u.nfs_fl.owner->host->h_lock); | ||
| 458 | list_del(&fl->fl_u.nfs_fl.list); | 456 | list_del(&fl->fl_u.nfs_fl.list); |
| 457 | spin_unlock(&fl->fl_u.nfs_fl.owner->host->h_lock); | ||
| 459 | nlm_put_lockowner(fl->fl_u.nfs_fl.owner); | 458 | nlm_put_lockowner(fl->fl_u.nfs_fl.owner); |
| 460 | } | 459 | } |
| 461 | 460 | ||
| @@ -721,9 +720,7 @@ static void nlmclnt_unlock_callback(struct rpc_task *task, void *data) | |||
| 721 | die: | 720 | die: |
| 722 | return; | 721 | return; |
| 723 | retry_rebind: | 722 | retry_rebind: |
| 724 | lock_kernel(); | ||
| 725 | nlm_rebind_host(req->a_host); | 723 | nlm_rebind_host(req->a_host); |
| 726 | unlock_kernel(); | ||
| 727 | retry_unlock: | 724 | retry_unlock: |
| 728 | rpc_restart_call(task); | 725 | rpc_restart_call(task); |
| 729 | } | 726 | } |
| @@ -801,9 +798,7 @@ retry_cancel: | |||
| 801 | /* Don't ever retry more than 3 times */ | 798 | /* Don't ever retry more than 3 times */ |
| 802 | if (req->a_retries++ >= NLMCLNT_MAX_RETRIES) | 799 | if (req->a_retries++ >= NLMCLNT_MAX_RETRIES) |
| 803 | goto die; | 800 | goto die; |
| 804 | lock_kernel(); | ||
| 805 | nlm_rebind_host(req->a_host); | 801 | nlm_rebind_host(req->a_host); |
| 806 | unlock_kernel(); | ||
| 807 | rpc_restart_call(task); | 802 | rpc_restart_call(task); |
| 808 | rpc_delay(task, 30 * HZ); | 803 | rpc_delay(task, 30 * HZ); |
| 809 | } | 804 | } |
diff --git a/fs/lockd/host.c b/fs/lockd/host.c index bb464d12104..25e21e4023b 100644 --- a/fs/lockd/host.c +++ b/fs/lockd/host.c | |||
| @@ -353,6 +353,7 @@ nlm_bind_host(struct nlm_host *host) | |||
| 353 | .to_retries = 5U, | 353 | .to_retries = 5U, |
| 354 | }; | 354 | }; |
| 355 | struct rpc_create_args args = { | 355 | struct rpc_create_args args = { |
| 356 | .net = &init_net, | ||
| 356 | .protocol = host->h_proto, | 357 | .protocol = host->h_proto, |
| 357 | .address = nlm_addr(host), | 358 | .address = nlm_addr(host), |
| 358 | .addrsize = host->h_addrlen, | 359 | .addrsize = host->h_addrlen, |
diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c index e3015464fba..e0c91894964 100644 --- a/fs/lockd/mon.c +++ b/fs/lockd/mon.c | |||
| @@ -69,6 +69,7 @@ static struct rpc_clnt *nsm_create(void) | |||
| 69 | .sin_addr.s_addr = htonl(INADDR_LOOPBACK), | 69 | .sin_addr.s_addr = htonl(INADDR_LOOPBACK), |
| 70 | }; | 70 | }; |
| 71 | struct rpc_create_args args = { | 71 | struct rpc_create_args args = { |
| 72 | .net = &init_net, | ||
| 72 | .protocol = XPRT_TRANSPORT_UDP, | 73 | .protocol = XPRT_TRANSPORT_UDP, |
| 73 | .address = (struct sockaddr *)&sin, | 74 | .address = (struct sockaddr *)&sin, |
| 74 | .addrsize = sizeof(sin), | 75 | .addrsize = sizeof(sin), |
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c index f1bacf1a039..abfff9d7979 100644 --- a/fs/lockd/svc.c +++ b/fs/lockd/svc.c | |||
| @@ -22,7 +22,6 @@ | |||
| 22 | #include <linux/in.h> | 22 | #include <linux/in.h> |
| 23 | #include <linux/uio.h> | 23 | #include <linux/uio.h> |
| 24 | #include <linux/smp.h> | 24 | #include <linux/smp.h> |
| 25 | #include <linux/smp_lock.h> | ||
| 26 | #include <linux/mutex.h> | 25 | #include <linux/mutex.h> |
| 27 | #include <linux/kthread.h> | 26 | #include <linux/kthread.h> |
| 28 | #include <linux/freezer.h> | 27 | #include <linux/freezer.h> |
| @@ -130,15 +129,6 @@ lockd(void *vrqstp) | |||
| 130 | 129 | ||
| 131 | dprintk("NFS locking service started (ver " LOCKD_VERSION ").\n"); | 130 | dprintk("NFS locking service started (ver " LOCKD_VERSION ").\n"); |
| 132 | 131 | ||
| 133 | /* | ||
| 134 | * FIXME: it would be nice if lockd didn't spend its entire life | ||
| 135 | * running under the BKL. At the very least, it would be good to | ||
| 136 | * have someone clarify what it's intended to protect here. I've | ||
| 137 | * seen some handwavy posts about posix locking needing to be | ||
| 138 | * done under the BKL, but it's far from clear. | ||
| 139 | */ | ||
| 140 | lock_kernel(); | ||
| 141 | |||
| 142 | if (!nlm_timeout) | 132 | if (!nlm_timeout) |
| 143 | nlm_timeout = LOCKD_DFLT_TIMEO; | 133 | nlm_timeout = LOCKD_DFLT_TIMEO; |
| 144 | nlmsvc_timeout = nlm_timeout * HZ; | 134 | nlmsvc_timeout = nlm_timeout * HZ; |
| @@ -195,7 +185,6 @@ lockd(void *vrqstp) | |||
| 195 | if (nlmsvc_ops) | 185 | if (nlmsvc_ops) |
| 196 | nlmsvc_invalidate_all(); | 186 | nlmsvc_invalidate_all(); |
| 197 | nlm_shutdown_hosts(); | 187 | nlm_shutdown_hosts(); |
| 198 | unlock_kernel(); | ||
| 199 | return 0; | 188 | return 0; |
| 200 | } | 189 | } |
| 201 | 190 | ||
| @@ -206,7 +195,7 @@ static int create_lockd_listener(struct svc_serv *serv, const char *name, | |||
| 206 | 195 | ||
| 207 | xprt = svc_find_xprt(serv, name, family, 0); | 196 | xprt = svc_find_xprt(serv, name, family, 0); |
| 208 | if (xprt == NULL) | 197 | if (xprt == NULL) |
| 209 | return svc_create_xprt(serv, name, family, port, | 198 | return svc_create_xprt(serv, name, &init_net, family, port, |
| 210 | SVC_SOCK_DEFAULTS); | 199 | SVC_SOCK_DEFAULTS); |
| 211 | svc_xprt_put(xprt); | 200 | svc_xprt_put(xprt); |
| 212 | return 0; | 201 | return 0; |
diff --git a/fs/lockd/svc4proc.c b/fs/lockd/svc4proc.c index 031c6569a13..a336e832475 100644 --- a/fs/lockd/svc4proc.c +++ b/fs/lockd/svc4proc.c | |||
| @@ -230,9 +230,7 @@ static void nlm4svc_callback_exit(struct rpc_task *task, void *data) | |||
| 230 | 230 | ||
| 231 | static void nlm4svc_callback_release(void *data) | 231 | static void nlm4svc_callback_release(void *data) |
| 232 | { | 232 | { |
| 233 | lock_kernel(); | ||
| 234 | nlm_release_call(data); | 233 | nlm_release_call(data); |
| 235 | unlock_kernel(); | ||
| 236 | } | 234 | } |
| 237 | 235 | ||
| 238 | static const struct rpc_call_ops nlm4svc_callback_ops = { | 236 | static const struct rpc_call_ops nlm4svc_callback_ops = { |
diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c index 84055d31bfc..c462d346acb 100644 --- a/fs/lockd/svclock.c +++ b/fs/lockd/svclock.c | |||
| @@ -52,12 +52,13 @@ static const struct rpc_call_ops nlmsvc_grant_ops; | |||
| 52 | * The list of blocked locks to retry | 52 | * The list of blocked locks to retry |
| 53 | */ | 53 | */ |
| 54 | static LIST_HEAD(nlm_blocked); | 54 | static LIST_HEAD(nlm_blocked); |
| 55 | static DEFINE_SPINLOCK(nlm_blocked_lock); | ||
| 55 | 56 | ||
| 56 | /* | 57 | /* |
| 57 | * Insert a blocked lock into the global list | 58 | * Insert a blocked lock into the global list |
| 58 | */ | 59 | */ |
| 59 | static void | 60 | static void |
| 60 | nlmsvc_insert_block(struct nlm_block *block, unsigned long when) | 61 | nlmsvc_insert_block_locked(struct nlm_block *block, unsigned long when) |
| 61 | { | 62 | { |
| 62 | struct nlm_block *b; | 63 | struct nlm_block *b; |
| 63 | struct list_head *pos; | 64 | struct list_head *pos; |
| @@ -87,6 +88,13 @@ nlmsvc_insert_block(struct nlm_block *block, unsigned long when) | |||
| 87 | block->b_when = when; | 88 | block->b_when = when; |
| 88 | } | 89 | } |
| 89 | 90 | ||
| 91 | static void nlmsvc_insert_block(struct nlm_block *block, unsigned long when) | ||
| 92 | { | ||
| 93 | spin_lock(&nlm_blocked_lock); | ||
| 94 | nlmsvc_insert_block_locked(block, when); | ||
| 95 | spin_unlock(&nlm_blocked_lock); | ||
| 96 | } | ||
| 97 | |||
| 90 | /* | 98 | /* |
| 91 | * Remove a block from the global list | 99 | * Remove a block from the global list |
| 92 | */ | 100 | */ |
| @@ -94,7 +102,9 @@ static inline void | |||
| 94 | nlmsvc_remove_block(struct nlm_block *block) | 102 | nlmsvc_remove_block(struct nlm_block *block) |
| 95 | { | 103 | { |
| 96 | if (!list_empty(&block->b_list)) { | 104 | if (!list_empty(&block->b_list)) { |
| 105 | spin_lock(&nlm_blocked_lock); | ||
| 97 | list_del_init(&block->b_list); | 106 | list_del_init(&block->b_list); |
| 107 | spin_unlock(&nlm_blocked_lock); | ||
| 98 | nlmsvc_release_block(block); | 108 | nlmsvc_release_block(block); |
| 99 | } | 109 | } |
| 100 | } | 110 | } |
| @@ -651,7 +661,7 @@ static int nlmsvc_grant_deferred(struct file_lock *fl, struct file_lock *conf, | |||
| 651 | struct nlm_block *block; | 661 | struct nlm_block *block; |
| 652 | int rc = -ENOENT; | 662 | int rc = -ENOENT; |
| 653 | 663 | ||
| 654 | lock_kernel(); | 664 | spin_lock(&nlm_blocked_lock); |
| 655 | list_for_each_entry(block, &nlm_blocked, b_list) { | 665 | list_for_each_entry(block, &nlm_blocked, b_list) { |
| 656 | if (nlm_compare_locks(&block->b_call->a_args.lock.fl, fl)) { | 666 | if (nlm_compare_locks(&block->b_call->a_args.lock.fl, fl)) { |
| 657 | dprintk("lockd: nlmsvc_notify_blocked block %p flags %d\n", | 667 | dprintk("lockd: nlmsvc_notify_blocked block %p flags %d\n", |
| @@ -665,13 +675,13 @@ static int nlmsvc_grant_deferred(struct file_lock *fl, struct file_lock *conf, | |||
| 665 | } else if (result == 0) | 675 | } else if (result == 0) |
| 666 | block->b_granted = 1; | 676 | block->b_granted = 1; |
| 667 | 677 | ||
| 668 | nlmsvc_insert_block(block, 0); | 678 | nlmsvc_insert_block_locked(block, 0); |
| 669 | svc_wake_up(block->b_daemon); | 679 | svc_wake_up(block->b_daemon); |
| 670 | rc = 0; | 680 | rc = 0; |
| 671 | break; | 681 | break; |
| 672 | } | 682 | } |
| 673 | } | 683 | } |
| 674 | unlock_kernel(); | 684 | spin_unlock(&nlm_blocked_lock); |
| 675 | if (rc == -ENOENT) | 685 | if (rc == -ENOENT) |
| 676 | printk(KERN_WARNING "lockd: grant for unknown block\n"); | 686 | printk(KERN_WARNING "lockd: grant for unknown block\n"); |
| 677 | return rc; | 687 | return rc; |
| @@ -690,14 +700,16 @@ nlmsvc_notify_blocked(struct file_lock *fl) | |||
| 690 | struct nlm_block *block; | 700 | struct nlm_block *block; |
| 691 | 701 | ||
| 692 | dprintk("lockd: VFS unblock notification for block %p\n", fl); | 702 | dprintk("lockd: VFS unblock notification for block %p\n", fl); |
| 703 | spin_lock(&nlm_blocked_lock); | ||
| 693 | list_for_each_entry(block, &nlm_blocked, b_list) { | 704 | list_for_each_entry(block, &nlm_blocked, b_list) { |
| 694 | if (nlm_compare_locks(&block->b_call->a_args.lock.fl, fl)) { | 705 | if (nlm_compare_locks(&block->b_call->a_args.lock.fl, fl)) { |
| 695 | nlmsvc_insert_block(block, 0); | 706 | nlmsvc_insert_block_locked(block, 0); |
| 707 | spin_unlock(&nlm_blocked_lock); | ||
| 696 | svc_wake_up(block->b_daemon); | 708 | svc_wake_up(block->b_daemon); |
| 697 | return; | 709 | return; |
| 698 | } | 710 | } |
| 699 | } | 711 | } |
| 700 | 712 | spin_unlock(&nlm_blocked_lock); | |
| 701 | printk(KERN_WARNING "lockd: notification for unknown block!\n"); | 713 | printk(KERN_WARNING "lockd: notification for unknown block!\n"); |
| 702 | } | 714 | } |
| 703 | 715 | ||
| @@ -803,7 +815,7 @@ static void nlmsvc_grant_callback(struct rpc_task *task, void *data) | |||
| 803 | 815 | ||
| 804 | dprintk("lockd: GRANT_MSG RPC callback\n"); | 816 | dprintk("lockd: GRANT_MSG RPC callback\n"); |
| 805 | 817 | ||
| 806 | lock_kernel(); | 818 | spin_lock(&nlm_blocked_lock); |
| 807 | /* if the block is not on a list at this point then it has | 819 | /* if the block is not on a list at this point then it has |
| 808 | * been invalidated. Don't try to requeue it. | 820 | * been invalidated. Don't try to requeue it. |
| 809 | * | 821 | * |
| @@ -825,19 +837,20 @@ static void nlmsvc_grant_callback(struct rpc_task *task, void *data) | |||
| 825 | /* Call was successful, now wait for client callback */ | 837 | /* Call was successful, now wait for client callback */ |
| 826 | timeout = 60 * HZ; | 838 | timeout = 60 * HZ; |
| 827 | } | 839 | } |
| 828 | nlmsvc_insert_block(block, timeout); | 840 | nlmsvc_insert_block_locked(block, timeout); |
| 829 | svc_wake_up(block->b_daemon); | 841 | svc_wake_up(block->b_daemon); |
| 830 | out: | 842 | out: |
| 831 | unlock_kernel(); | 843 | spin_unlock(&nlm_blocked_lock); |
| 832 | } | 844 | } |
| 833 | 845 | ||
| 846 | /* | ||
| 847 | * FIXME: nlmsvc_release_block() grabs a mutex. This is not allowed for an | ||
| 848 | * .rpc_release rpc_call_op | ||
| 849 | */ | ||
| 834 | static void nlmsvc_grant_release(void *data) | 850 | static void nlmsvc_grant_release(void *data) |
| 835 | { | 851 | { |
| 836 | struct nlm_rqst *call = data; | 852 | struct nlm_rqst *call = data; |
| 837 | |||
| 838 | lock_kernel(); | ||
| 839 | nlmsvc_release_block(call->a_block); | 853 | nlmsvc_release_block(call->a_block); |
| 840 | unlock_kernel(); | ||
| 841 | } | 854 | } |
| 842 | 855 | ||
| 843 | static const struct rpc_call_ops nlmsvc_grant_ops = { | 856 | static const struct rpc_call_ops nlmsvc_grant_ops = { |
diff --git a/fs/lockd/svcproc.c b/fs/lockd/svcproc.c index 0f2ab741ae7..c3069f38d60 100644 --- a/fs/lockd/svcproc.c +++ b/fs/lockd/svcproc.c | |||
| @@ -260,9 +260,7 @@ static void nlmsvc_callback_exit(struct rpc_task *task, void *data) | |||
| 260 | 260 | ||
| 261 | static void nlmsvc_callback_release(void *data) | 261 | static void nlmsvc_callback_release(void *data) |
| 262 | { | 262 | { |
| 263 | lock_kernel(); | ||
| 264 | nlm_release_call(data); | 263 | nlm_release_call(data); |
| 265 | unlock_kernel(); | ||
| 266 | } | 264 | } |
| 267 | 265 | ||
| 268 | static const struct rpc_call_ops nlmsvc_callback_ops = { | 266 | static const struct rpc_call_ops nlmsvc_callback_ops = { |
diff --git a/fs/lockd/svcsubs.c b/fs/lockd/svcsubs.c index d0ef94cfb3d..1ca0679c80b 100644 --- a/fs/lockd/svcsubs.c +++ b/fs/lockd/svcsubs.c | |||
| @@ -170,6 +170,7 @@ nlm_traverse_locks(struct nlm_host *host, struct nlm_file *file, | |||
| 170 | 170 | ||
| 171 | again: | 171 | again: |
| 172 | file->f_locks = 0; | 172 | file->f_locks = 0; |
| 173 | lock_flocks(); /* protects i_flock list */ | ||
| 173 | for (fl = inode->i_flock; fl; fl = fl->fl_next) { | 174 | for (fl = inode->i_flock; fl; fl = fl->fl_next) { |
| 174 | if (fl->fl_lmops != &nlmsvc_lock_operations) | 175 | if (fl->fl_lmops != &nlmsvc_lock_operations) |
| 175 | continue; | 176 | continue; |
| @@ -181,6 +182,7 @@ again: | |||
| 181 | if (match(lockhost, host)) { | 182 | if (match(lockhost, host)) { |
| 182 | struct file_lock lock = *fl; | 183 | struct file_lock lock = *fl; |
| 183 | 184 | ||
| 185 | unlock_flocks(); | ||
| 184 | lock.fl_type = F_UNLCK; | 186 | lock.fl_type = F_UNLCK; |
| 185 | lock.fl_start = 0; | 187 | lock.fl_start = 0; |
| 186 | lock.fl_end = OFFSET_MAX; | 188 | lock.fl_end = OFFSET_MAX; |
| @@ -192,6 +194,7 @@ again: | |||
| 192 | goto again; | 194 | goto again; |
| 193 | } | 195 | } |
| 194 | } | 196 | } |
| 197 | unlock_flocks(); | ||
| 195 | 198 | ||
| 196 | return 0; | 199 | return 0; |
| 197 | } | 200 | } |
| @@ -226,10 +229,14 @@ nlm_file_inuse(struct nlm_file *file) | |||
| 226 | if (file->f_count || !list_empty(&file->f_blocks) || file->f_shares) | 229 | if (file->f_count || !list_empty(&file->f_blocks) || file->f_shares) |
| 227 | return 1; | 230 | return 1; |
| 228 | 231 | ||
| 232 | lock_flocks(); | ||
| 229 | for (fl = inode->i_flock; fl; fl = fl->fl_next) { | 233 | for (fl = inode->i_flock; fl; fl = fl->fl_next) { |
| 230 | if (fl->fl_lmops == &nlmsvc_lock_operations) | 234 | if (fl->fl_lmops == &nlmsvc_lock_operations) { |
| 235 | unlock_flocks(); | ||
| 231 | return 1; | 236 | return 1; |
| 237 | } | ||
| 232 | } | 238 | } |
| 239 | unlock_flocks(); | ||
| 233 | file->f_locks = 0; | 240 | file->f_locks = 0; |
| 234 | return 0; | 241 | return 0; |
| 235 | } | 242 | } |
