diff options
author | David Teigland <teigland@redhat.com> | 2006-07-18 18:24:04 +0200 |
---|---|---|
committer | Steven Whitehouse <swhiteho@redhat.com> | 2006-07-20 06:11:15 +0200 |
commit | 34e22bed19013c77f942083e25cfc7adf6c71a8f (patch) | |
tree | 18c44bb1e3e3d40fc04f61020497f935a97df576 /fs/dlm/user.c | |
parent | [DLM] [RFC: -mm patch] fs/dlm/lock.c: unexport dlm_lvb_operations (diff) | |
download | linux-34e22bed19013c77f942083e25cfc7adf6c71a8f.tar.xz linux-34e22bed19013c77f942083e25cfc7adf6c71a8f.zip |
[DLM] fix leaking user locks
User NOQUEUE lock requests to a remote node that failed with -EAGAIN were
never being removed from a process's list of locks.
Signed-off-by: David Teigland <teigland@redhat.com>
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/dlm/user.c')
-rw-r--r-- | fs/dlm/user.c | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/fs/dlm/user.c b/fs/dlm/user.c index 1f05960a916f..fd19caf9af97 100644 --- a/fs/dlm/user.c +++ b/fs/dlm/user.c @@ -133,6 +133,7 @@ void dlm_user_add_ast(struct dlm_lkb *lkb, int type) struct dlm_ls *ls; struct dlm_user_args *ua; struct dlm_user_proc *proc; + int remove_ownqueue = 0; /* dlm_clear_proc_locks() sets ORPHAN/DEAD flag on each lkb before dealing with it. We need to check this @@ -171,6 +172,14 @@ void dlm_user_add_ast(struct dlm_lkb *lkb, int type) wake_up_interruptible(&proc->wait); } + /* noqueue requests that fail may need to be removed from the + proc's locks list, there should be a better way of detecting + this situation than checking all these things... */ + + if (type == AST_COMP && lkb->lkb_grmode == DLM_LOCK_IV && + ua->lksb.sb_status == -EAGAIN && !list_empty(&lkb->lkb_ownqueue)) + remove_ownqueue = 1; + /* We want to copy the lvb to userspace when the completion ast is read if the status is 0, the lock has an lvb and lvb_ops says we should. We could probably have set_lvb_lock() @@ -185,6 +194,13 @@ void dlm_user_add_ast(struct dlm_lkb *lkb, int type) ua->update_user_lvb = 0; spin_unlock(&proc->asts_spin); + + if (remove_ownqueue) { + spin_lock(&ua->proc->locks_spin); + list_del_init(&lkb->lkb_ownqueue); + spin_unlock(&ua->proc->locks_spin); + dlm_put_lkb(lkb); + } out: mutex_unlock(&ls->ls_clear_proc_locks); } |