]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
DEVEL15-rx-do-not-race-current-packet-20090105
authorJeffrey Altman <jaltman@your-file-system.com>
Mon, 5 Jan 2009 23:13:08 +0000 (23:13 +0000)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Mon, 5 Jan 2009 23:13:08 +0000 (23:13 +0000)
LICENSE MIT

Throughout rx_rdwr.c functions allocate a register variable 'cp'
which is used to optimize access to call->currentPacket.
Unfortunately, if the call->lock is dropped (for example, CV_WAIT)
the synchronization between the two is lost.  This delta re-syncs
'cp' and call->currentPacket after each location where the call->lock
may be dropped.

(cherry picked from commit 423ab97eee35f57beeb481cac2159d28dea20577)

src/rx/rx_rdwr.c

index 3ded6c30e9b60288614b9cad1995442e1dfcf581..63185f8453b5e106cded85e1afb13bf3297f3cb2 100644 (file)
@@ -241,6 +241,8 @@ MTUXXX  doesn't there need to be an "else" here ???
                    osi_rxSleep(&call->rq);
 #endif
                }
+                /* cp is no longer valid since we may have given up the lock */
+                cp = call->currentPacket;
 
                call->startWait = 0;
 #ifdef RX_ENABLE_LOCKS
@@ -1116,7 +1118,7 @@ rx_WritevAlloc(struct rx_call *call, struct iovec *iov, int *nio, int maxio,
 int
 rxi_WritevProc(struct rx_call *call, struct iovec *iov, int nio, int nbytes)
 {
-    struct rx_packet *cp = call->currentPacket;
+    struct rx_packet *cp = NULL;
     struct rx_call *p, *np;
     int nextio;
     int requestCount;
@@ -1143,6 +1145,8 @@ rxi_WritevProc(struct rx_call *call, struct iovec *iov, int nio, int nbytes)
 #endif /* RX_ENABLE_LOCKS */
     }
 #endif /* AFS_GLOBAL_RXLOCK_KERNEL */
+    /* cp is no longer valid since we may have given up the lock */
+    cp = call->currentPacket;
 
     if (call->error) {
        if (cp) {
@@ -1278,6 +1282,8 @@ rxi_WritevProc(struct rx_call *call, struct iovec *iov, int nio, int nbytes)
 #endif
        call->startWait = 0;
     }
+    /* cp is no longer valid since we may have given up the lock */
+    cp = call->currentPacket;
 
     if (call->error) {
        if (cp) {
@@ -1310,7 +1316,7 @@ rx_WritevProc(struct rx_call *call, struct iovec *iov, int nio, int nbytes)
 void
 rxi_FlushWrite(register struct rx_call *call)
 {
-    register struct rx_packet *cp = call->currentPacket;
+    register struct rx_packet *cp = NULL;
 
     /* Free any packets from the last call to ReadvProc/WritevProc */
     if (queue_IsNotEmpty(&call->iovq)) {
@@ -1353,6 +1359,9 @@ rxi_FlushWrite(register struct rx_call *call)
        }
 #endif /* AFS_GLOBAL_RXLOCK_KERNEL */
 
+        /* cp is no longer valid since we may have given up the lock */
+        cp = call->currentPacket;
+
        if (cp) {
            /* cp->length is only supposed to be the user's data */
            /* cp->length was already set to (then-current)