diff options
Diffstat (limited to 'fs/lockd/clntlock.c')
-rw-r--r-- | fs/lockd/clntlock.c | 15 |
1 files changed, 10 insertions, 5 deletions
diff --git a/fs/lockd/clntlock.c b/fs/lockd/clntlock.c index 64fd427c993c..d5bb86866e6c 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 | } |