diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/lockd/svclock.c | 15 | ||||
-rw-r--r-- | fs/locks.c | 7 |
2 files changed, 16 insertions, 6 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: * It is the caller's responsibility to check whether the file * can be closed hereafter. */ -static void +static int nlmsvc_delete_block(struct nlm_block *block, int unlock) { struct file_lock *fl = &block->b_call.a_args.lock.fl; struct nlm_file *file = block->b_file; struct nlm_block **bp; + int status = 0; dprintk("lockd: deleting block %p...\n", block); /* Remove block from list */ nlmsvc_remove_block(block); - posix_unblock_lock(file->f_file, fl); + if (unlock) + status = posix_unblock_lock(file->f_file, fl); /* If the block is in the middle of a GRANT callback, * don't kill it yet. */ if (block->b_incall) { nlmsvc_insert_block(block, NLM_NEVER); block->b_done = 1; - return; + return status; } /* Remove block from file's list of blocks */ @@ -260,6 +262,7 @@ nlmsvc_delete_block(struct nlm_block *block, int unlock) nlm_release_host(block->b_host); nlmclnt_freegrantargs(&block->b_call); kfree(block); + return status; } /* @@ -270,6 +273,7 @@ int nlmsvc_traverse_blocks(struct nlm_host *host, struct nlm_file *file, int action) { struct nlm_block *block, *next; + /* XXX: Will everything get cleaned up if we don't unlock here? */ down(&file->f_sema); for (block = file->f_blocks; block; block = next) { @@ -439,6 +443,7 @@ u32 nlmsvc_cancel_blocked(struct nlm_file *file, struct nlm_lock *lock) { struct nlm_block *block; + int status = 0; dprintk("lockd: nlmsvc_cancel(%s/%ld, pi=%d, %Ld-%Ld)\n", 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) down(&file->f_sema); if ((block = nlmsvc_lookup_block(file, lock, 1)) != NULL) - nlmsvc_delete_block(block, 1); + status = nlmsvc_delete_block(block, 1); up(&file->f_sema); - return nlm_granted; + return status ? nlm_lck_denied : nlm_granted; } /* 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); * * lockd needs to block waiting for locks. */ -void +int posix_unblock_lock(struct file *filp, struct file_lock *waiter) { + int status = 0; + lock_kernel(); if (waiter->fl_next) __locks_delete_block(waiter); + else + status = -ENOENT; unlock_kernel(); + return status; } EXPORT_SYMBOL(posix_unblock_lock); |