CVSROOT:        /cvs/cluster
Module name:    cluster
Changes by:     [EMAIL PROTECTED]       2007-08-07 19:20:55

Modified files:
        group/dlm_controld: deadlock.c 

Log message:
        don't add the same transaction to a waitfor list more than once

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/group/dlm_controld/deadlock.c.diff?cvsroot=cluster&r1=1.2&r2=1.3

--- cluster/group/dlm_controld/deadlock.c       2007/08/06 21:50:26     1.2
+++ cluster/group/dlm_controld/deadlock.c       2007/08/07 19:20:54     1.3
@@ -732,7 +732,8 @@
                return;
        }
 
-       log_group(ls, "write_checkpoint: open ckpt handle %llx", (long long)h);
+       log_group(ls, "write_checkpoint: open ckpt handle %llx",
+                 (unsigned long long)h);
        ls->lock_ckpt_handle = (uint64_t) h;
 
        list_for_each_entry(r, &ls->resources, list) {
@@ -791,7 +792,7 @@
        }
        if (error != CPG_OK) {
                log_error("cpg_mcast_joined error %d handle %llx",
-                         (int)error, (long long)h);
+                         (int)error, (unsigned long long)h);
                disable_deadlock();
                return -1;
        }
@@ -1232,7 +1233,7 @@
 
        if (waiting_lkb->trans->xid == granted_lkb->trans->xid) {
                log_debug("waiting and granted same trans %llx",
-                         (long long)waiting_lkb->trans->xid);
+                         (unsigned long long)waiting_lkb->trans->xid);
                return 0;
        }
 
@@ -1240,19 +1241,35 @@
                                waiting_lkb->lock.rqmode);
 }
 
-/* TODO: don't add new waitfor trans if we're already waiting for the same
-   trans for another lock */
+static int in_waitfor(struct trans *tr, struct trans *add_tr)
+{
+       int i;
+
+       for (i = 0; i < tr->waitfor_alloc; i++) {
+               if (!tr->waitfor[i])
+                       continue;
+               if (tr->waitfor[i] == add_tr)
+                       return 1;
+       }
+       return 0;
+}
 
-static void add_waitfor(struct dlm_lkb *waiting_lkb,
+static void add_waitfor(struct lockspace *ls, struct dlm_lkb *waiting_lkb,
                        struct dlm_lkb *granted_lkb)
 {
-       struct trans *tr;
+       struct trans *tr = waiting_lkb->trans;
        int old_alloc, i;
 
        if (locks_compat(waiting_lkb, granted_lkb))
                return;
 
-       tr = waiting_lkb->trans;
+       /* don't add the same trans to the waitfor list multiple times */
+       if (tr->waitfor_count && in_waitfor(tr, granted_lkb->trans)) {
+               log_group(ls, "trans %llx already waiting for trans %llx",
+                         (unsigned long long)tr->xid,
+                         (unsigned long long)granted_lkb->trans->xid);
+               return;
+       }
 
        if (tr->waitfor_count == tr->waitfor_alloc) {
                old_alloc = tr->waitfor_alloc;
@@ -1289,7 +1306,7 @@
                                if (granted_lkb->lock.status==DLM_LKSTS_WAITING)
                                        continue;
                                /* granted_lkb status is GRANTED or CONVERT */
-                               add_waitfor(waiting_lkb, granted_lkb);
+                               add_waitfor(ls, waiting_lkb, granted_lkb);
                        }
                }
        }

Reply via email to