aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/lockd/svclock.c15
-rw-r--r--fs/locks.c7
-rw-r--r--include/linux/fs.h2
3 files changed, 17 insertions, 7 deletions
diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c
index b56d439bad82..9cfced65d4a2 100644
--- a/fs/lockd/svclock.c
+++ b/fs/lockd/svclock.c
@@ -227,25 +227,27 @@ failed:
227 * It is the caller's responsibility to check whether the file 227 * It is the caller's responsibility to check whether the file
228 * can be closed hereafter. 228 * can be closed hereafter.
229 */ 229 */
230static void 230static int
231nlmsvc_delete_block(struct nlm_block *block, int unlock) 231nlmsvc_delete_block(struct nlm_block *block, int unlock)
232{ 232{
233 struct file_lock *fl = &block->b_call.a_args.lock.fl; 233 struct file_lock *fl = &block->b_call.a_args.lock.fl;
234 struct nlm_file *file = block->b_file; 234 struct nlm_file *file = block->b_file;
235 struct nlm_block **bp; 235 struct nlm_block **bp;
236 int status = 0;
236 237
237 dprintk("lockd: deleting block %p...\n", block); 238 dprintk("lockd: deleting block %p...\n", block);
238 239
239 /* Remove block from list */ 240 /* Remove block from list */
240 nlmsvc_remove_block(block); 241 nlmsvc_remove_block(block);
241 posix_unblock_lock(file->f_file, fl); 242 if (unlock)
243 status = posix_unblock_lock(file->f_file, fl);
242 244
243 /* If the block is in the middle of a GRANT callback, 245 /* If the block is in the middle of a GRANT callback,
244 * don't kill it yet. */ 246 * don't kill it yet. */
245 if (block->b_incall) { 247 if (block->b_incall) {
246 nlmsvc_insert_block(block, NLM_NEVER); 248 nlmsvc_insert_block(block, NLM_NEVER);
247 block->b_done = 1; 249 block->b_done = 1;
248 return; 250 return status;
249 } 251 }
250 252
251 /* Remove block from file's list of blocks */ 253 /* Remove block from file's list of blocks */
@@ -260,6 +262,7 @@ nlmsvc_delete_block(struct nlm_block *block, int unlock)
260 nlm_release_host(block->b_host); 262 nlm_release_host(block->b_host);
261 nlmclnt_freegrantargs(&block->b_call); 263 nlmclnt_freegrantargs(&block->b_call);
262 kfree(block); 264 kfree(block);
265 return status;
263} 266}
264 267
265/* 268/*
@@ -270,6 +273,7 @@ int
270nlmsvc_traverse_blocks(struct nlm_host *host, struct nlm_file *file, int action) 273nlmsvc_traverse_blocks(struct nlm_host *host, struct nlm_file *file, int action)
271{ 274{
272 struct nlm_block *block, *next; 275 struct nlm_block *block, *next;
276 /* XXX: Will everything get cleaned up if we don't unlock here? */
273 277
274 down(&file->f_sema); 278 down(&file->f_sema);
275 for (block = file->f_blocks; block; block = next) { 279 for (block = file->f_blocks; block; block = next) {
@@ -439,6 +443,7 @@ u32
439nlmsvc_cancel_blocked(struct nlm_file *file, struct nlm_lock *lock) 443nlmsvc_cancel_blocked(struct nlm_file *file, struct nlm_lock *lock)
440{ 444{
441 struct nlm_block *block; 445 struct nlm_block *block;
446 int status = 0;
442 447
443 dprintk("lockd: nlmsvc_cancel(%s/%ld, pi=%d, %Ld-%Ld)\n", 448 dprintk("lockd: nlmsvc_cancel(%s/%ld, pi=%d, %Ld-%Ld)\n",
444 file->f_file->f_dentry->d_inode->i_sb->s_id, 449 file->f_file->f_dentry->d_inode->i_sb->s_id,
@@ -449,9 +454,9 @@ nlmsvc_cancel_blocked(struct nlm_file *file, struct nlm_lock *lock)
449 454
450 down(&file->f_sema); 455 down(&file->f_sema);
451 if ((block = nlmsvc_lookup_block(file, lock, 1)) != NULL) 456 if ((block = nlmsvc_lookup_block(file, lock, 1)) != NULL)
452 nlmsvc_delete_block(block, 1); 457 status = nlmsvc_delete_block(block, 1);
453 up(&file->f_sema); 458 up(&file->f_sema);
454 return nlm_granted; 459 return status ? nlm_lck_denied : nlm_granted;
455} 460}
456 461
457/* 462/*
diff --git a/fs/locks.c b/fs/locks.c
index 75650d52fe60..fb32d6218e21 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -1958,13 +1958,18 @@ EXPORT_SYMBOL(posix_block_lock);
1958 * 1958 *
1959 * lockd needs to block waiting for locks. 1959 * lockd needs to block waiting for locks.
1960 */ 1960 */
1961void 1961int
1962posix_unblock_lock(struct file *filp, struct file_lock *waiter) 1962posix_unblock_lock(struct file *filp, struct file_lock *waiter)
1963{ 1963{
1964 int status = 0;
1965
1964 lock_kernel(); 1966 lock_kernel();
1965 if (waiter->fl_next) 1967 if (waiter->fl_next)
1966 __locks_delete_block(waiter); 1968 __locks_delete_block(waiter);
1969 else
1970 status = -ENOENT;
1967 unlock_kernel(); 1971 unlock_kernel();
1972 return status;
1968} 1973}
1969 1974
1970EXPORT_SYMBOL(posix_unblock_lock); 1975EXPORT_SYMBOL(posix_unblock_lock);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 115e72be25d0..2c9c48d65630 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -760,7 +760,7 @@ extern struct file_lock *posix_test_lock(struct file *, struct file_lock *);
760extern int posix_lock_file(struct file *, struct file_lock *); 760extern int posix_lock_file(struct file *, struct file_lock *);
761extern int posix_lock_file_wait(struct file *, struct file_lock *); 761extern int posix_lock_file_wait(struct file *, struct file_lock *);
762extern void posix_block_lock(struct file_lock *, struct file_lock *); 762extern void posix_block_lock(struct file_lock *, struct file_lock *);
763extern void posix_unblock_lock(struct file *, struct file_lock *); 763extern int posix_unblock_lock(struct file *, struct file_lock *);
764extern int posix_locks_deadlock(struct file_lock *, struct file_lock *); 764extern int posix_locks_deadlock(struct file_lock *, struct file_lock *);
765extern int flock_lock_file_wait(struct file *filp, struct file_lock *fl); 765extern int flock_lock_file_wait(struct file *filp, struct file_lock *fl);
766extern int __break_lease(struct inode *inode, unsigned int flags); 766extern int __break_lease(struct inode *inode, unsigned int flags);