]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - fs/dlm/lock.c
Merge branch 'master' into for_paulus
[linux-2.6-omap-h63xx.git] / fs / dlm / lock.c
index 5bac9827ded30460eb3f4be9936147c7a09800e9..e725005fafd024cd41de5bdb9c0271497a7d2e1f 100644 (file)
@@ -754,6 +754,11 @@ static void add_to_waiters(struct dlm_lkb *lkb, int mstype)
        mutex_unlock(&ls->ls_waiters_mutex);
 }
 
+/* We clear the RESEND flag because we might be taking an lkb off the waiters
+   list as part of process_requestqueue (e.g. a lookup that has an optimized
+   request reply on the requestqueue) between dlm_recover_waiters_pre() which
+   set RESEND and dlm_recover_waiters_post() */
+
 static int _remove_from_waiters(struct dlm_lkb *lkb)
 {
        int error = 0;
@@ -764,6 +769,7 @@ static int _remove_from_waiters(struct dlm_lkb *lkb)
                goto out;
        }
        lkb->lkb_wait_type = 0;
+       lkb->lkb_flags &= ~DLM_IFL_RESEND;
        list_del(&lkb->lkb_wait_reply);
        unhold_lkb(lkb);
  out:
@@ -3018,7 +3024,7 @@ int dlm_receive_message(struct dlm_header *hd, int nodeid, int recovery)
 {
        struct dlm_message *ms = (struct dlm_message *) hd;
        struct dlm_ls *ls;
-       int error;
+       int error = 0;
 
        if (!recovery)
                dlm_message_in(ms);
@@ -3135,7 +3141,7 @@ int dlm_receive_message(struct dlm_header *hd, int nodeid, int recovery)
  out:
        dlm_put_lockspace(ls);
        dlm_astd_wake();
-       return 0;
+       return error;
 }
 
 
@@ -3637,7 +3643,7 @@ int dlm_user_request(struct dlm_ls *ls, struct dlm_user_args *ua,
        }
 
        if (flags & DLM_LKF_VALBLK) {
-               ua->lksb.sb_lvbptr = kmalloc(DLM_USER_LVB_LEN, GFP_KERNEL);
+               ua->lksb.sb_lvbptr = kzalloc(DLM_USER_LVB_LEN, GFP_KERNEL);
                if (!ua->lksb.sb_lvbptr) {
                        kfree(ua);
                        __put_lkb(ls, lkb);
@@ -3706,7 +3712,7 @@ int dlm_user_convert(struct dlm_ls *ls, struct dlm_user_args *ua_tmp,
        ua = (struct dlm_user_args *)lkb->lkb_astparam;
 
        if (flags & DLM_LKF_VALBLK && !ua->lksb.sb_lvbptr) {
-               ua->lksb.sb_lvbptr = kmalloc(DLM_USER_LVB_LEN, GFP_KERNEL);
+               ua->lksb.sb_lvbptr = kzalloc(DLM_USER_LVB_LEN, GFP_KERNEL);
                if (!ua->lksb.sb_lvbptr) {
                        error = -ENOMEM;
                        goto out_put;
@@ -3772,12 +3778,10 @@ int dlm_user_unlock(struct dlm_ls *ls, struct dlm_user_args *ua_tmp,
                goto out_put;
 
        spin_lock(&ua->proc->locks_spin);
-       list_del_init(&lkb->lkb_ownqueue);
+       /* dlm_user_add_ast() may have already taken lkb off the proc list */
+       if (!list_empty(&lkb->lkb_ownqueue))
+               list_move(&lkb->lkb_ownqueue, &ua->proc->unlocking);
        spin_unlock(&ua->proc->locks_spin);
-
-       /* this removes the reference for the proc->locks list added by
-          dlm_user_request */
-       unhold_lkb(lkb);
  out_put:
        dlm_put_lkb(lkb);
  out:
@@ -3817,9 +3821,8 @@ int dlm_user_cancel(struct dlm_ls *ls, struct dlm_user_args *ua_tmp,
        /* this lkb was removed from the WAITING queue */
        if (lkb->lkb_grmode == DLM_LOCK_IV) {
                spin_lock(&ua->proc->locks_spin);
-               list_del_init(&lkb->lkb_ownqueue);
+               list_move(&lkb->lkb_ownqueue, &ua->proc->unlocking);
                spin_unlock(&ua->proc->locks_spin);
-               unhold_lkb(lkb);
        }
  out_put:
        dlm_put_lkb(lkb);
@@ -3880,11 +3883,6 @@ void dlm_clear_proc_locks(struct dlm_ls *ls, struct dlm_user_proc *proc)
        mutex_lock(&ls->ls_clear_proc_locks);
 
        list_for_each_entry_safe(lkb, safe, &proc->locks, lkb_ownqueue) {
-               if (lkb->lkb_ast_type) {
-                       list_del(&lkb->lkb_astqueue);
-                       unhold_lkb(lkb);
-               }
-
                list_del_init(&lkb->lkb_ownqueue);
 
                if (lkb->lkb_exflags & DLM_LKF_PERSISTENT) {
@@ -3901,6 +3899,20 @@ void dlm_clear_proc_locks(struct dlm_ls *ls, struct dlm_user_proc *proc)
 
                dlm_put_lkb(lkb);
        }
+
+       /* in-progress unlocks */
+       list_for_each_entry_safe(lkb, safe, &proc->unlocking, lkb_ownqueue) {
+               list_del_init(&lkb->lkb_ownqueue);
+               lkb->lkb_flags |= DLM_IFL_DEAD;
+               dlm_put_lkb(lkb);
+       }
+
+       list_for_each_entry_safe(lkb, safe, &proc->asts, lkb_astqueue) {
+               list_del(&lkb->lkb_astqueue);
+               dlm_put_lkb(lkb);
+       }
+
        mutex_unlock(&ls->ls_clear_proc_locks);
        unlock_recovery(ls);
 }
+