[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>
diff --git a/fs/dlm/user.c b/fs/dlm/user.c
index 1f05960..fd19caf 100644
--- a/fs/dlm/user.c
+++ b/fs/dlm/user.c
@@ -133,6 +133,7 @@
 	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 @@
 		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 @@
 		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);
 }