]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
STABLE14-viced-qsort-cba-before-multibreakcallback-to-avoid-lockup-20080218
authorDerrick Brashear <shadow@dementia.org>
Mon, 18 Feb 2008 19:22:48 +0000 (19:22 +0000)
committerDerrick Brashear <shadow@dementia.org>
Mon, 18 Feb 2008 19:22:48 +0000 (19:22 +0000)
LICENSE IPL10

my code, though, this is a result of a problem reported by Chaskiel Grundman and analysis by him, Jeff Altman and myself.

I'm just checking in my implementation. In any case, the issue this addresses
is one where we can end up in makecall_waiting in rx on multiple connections
when we multibreakcallback because the lists are sorted differently and each has "pending" calls on a different connection. by sorting by index we will not
block on another caller while also holding what they're after

(cherry picked from commit 7421feda944d5fa05f5223528a69f23a7bb0b724)

src/viced/callback.c

index 076ba08f9e40ac70983c08d84b24d23d61c31319..f6fe2cd9624a8d7b3767922e90ed48d1f1080de5 100644 (file)
@@ -749,6 +749,14 @@ AddCallBack1_r(struct host *host, AFSFid * fid, afs_uint32 * thead, int type,
     return 0;
 }
 
+static int
+CompareCBA(const void *e1, const void *e2)
+{
+    const struct cbstruct *cba1 = (const struct cbstruct *)e1;
+    const struct cbstruct *cba2 = (const struct cbstruct *)e2;
+    return ((cba1->hp)->index - (cba2->hp)->index);
+}
+
 /* Take an array full of hosts, all held.  Break callbacks to them, and 
  * release the holds once you're done, except don't release xhost.  xhost 
  * may be NULL.  Currently only works for a single Fid in afidp array.
@@ -778,6 +786,9 @@ MultiBreakCallBack_r(struct cbstruct cba[], int ncbas,
 
     assert(ncbas <= MAX_CB_HOSTS);
 
+    /* sort cba list to avoid makecall issues */
+    qsort(cba, ncbas, sizeof(struct cbstruct), CompareCBA);
+
     /* set up conns for multi-call */
     for (i = 0, j = 0; i < ncbas; i++) {
        struct host *thishost = cba[i].hp;