diff options
-rw-r--r-- | fs/lockd/svclock.c | 15 | ||||
-rw-r--r-- | fs/locks.c | 7 | ||||
-rw-r--r-- | include/linux/fs.h | 2 |
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 | */ |
230 | static void | 230 | static int |
231 | nlmsvc_delete_block(struct nlm_block *block, int unlock) | 231 | nlmsvc_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 | |||
270 | nlmsvc_traverse_blocks(struct nlm_host *host, struct nlm_file *file, int action) | 273 | nlmsvc_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 | |||
439 | nlmsvc_cancel_blocked(struct nlm_file *file, struct nlm_lock *lock) | 443 | nlmsvc_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 | */ |
1961 | void | 1961 | int |
1962 | posix_unblock_lock(struct file *filp, struct file_lock *waiter) | 1962 | posix_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 | ||
1970 | EXPORT_SYMBOL(posix_unblock_lock); | 1975 | EXPORT_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 *); | |||
760 | extern int posix_lock_file(struct file *, struct file_lock *); | 760 | extern int posix_lock_file(struct file *, struct file_lock *); |
761 | extern int posix_lock_file_wait(struct file *, struct file_lock *); | 761 | extern int posix_lock_file_wait(struct file *, struct file_lock *); |
762 | extern void posix_block_lock(struct file_lock *, struct file_lock *); | 762 | extern void posix_block_lock(struct file_lock *, struct file_lock *); |
763 | extern void posix_unblock_lock(struct file *, struct file_lock *); | 763 | extern int posix_unblock_lock(struct file *, struct file_lock *); |
764 | extern int posix_locks_deadlock(struct file_lock *, struct file_lock *); | 764 | extern int posix_locks_deadlock(struct file_lock *, struct file_lock *); |
765 | extern int flock_lock_file_wait(struct file *filp, struct file_lock *fl); | 765 | extern int flock_lock_file_wait(struct file *filp, struct file_lock *fl); |
766 | extern int __break_lease(struct inode *inode, unsigned int flags); | 766 | extern int __break_lease(struct inode *inode, unsigned int flags); |