drop afs_xserver lock during GetCapabilities
authorDerrick Brashear <shadow@dementia.org>
Wed, 14 Apr 2010 22:33:47 +0000 (18:33 -0400)
committerDerrick Brashear <shadow@dementia.org>
Thu, 15 Apr 2010 02:06:17 +0000 (19:06 -0700)
new contact to a fileserver can trigger an InitCallBackStateN RPC
to us, which our agent will need afs_xserver to handle. don't hold it;
we only need it to fill in capabilities. racing here is ok.

Change-Id: Ie0aaea3ab462e421bd31ba3b703d8cd0cb0d61df
Reviewed-on: http://gerrit.openafs.org/1754
Reviewed-by: Marc Dionne <marc.c.dionne@gmail.com>
Tested-by: Marc Dionne <marc.c.dionne@gmail.com>
Reviewed-by: Andrew Deason <adeason@sinenomine.net>
Tested-by: Andrew Deason <adeason@sinenomine.net>
Reviewed-by: Derrick Brashear <shadow@dementia.org>
Tested-by: Derrick Brashear <shadow@dementia.org>

src/afs/afs_server.c

index 01e81a4..6b4a02c 100644 (file)
@@ -1703,12 +1703,18 @@ afs_GetCapabilities(struct server *ts)
                                                                SHARED_LOCK);
     if ( !tc )
        return;
+    /* InitCallBackStateN, triggered by our RPC, may need this */
+    ReleaseWriteLock(&afs_xserver);
     code = RXAFS_GetCapabilities(tc->id, &caps);
-    if ( code && code != RXGEN_OPCODE )
-       afs_warn("RXAFS_GetCapabilities failed with code %d\n", code);
-    else
-       ts->flags |= SCAPS_KNOWN;
+    ObtainWriteLock(&afs_xserver, 723);
     afs_PutConn(tc, SHARED_LOCK);
+    if ( code && code != RXGEN_OPCODE ) {
+       afs_warn("RXAFS_GetCapabilities failed with code %d\n", code);
+       /* better not be anything to free. we failed! */
+       return;
+    }
+
+    ts->flags |= SCAPS_KNOWN;
 
     if ( caps.Capabilities_len > 0 ) {
        ts->capabilities = caps.Capabilities_val[0];
@@ -1919,10 +1925,11 @@ afs_GetServer(afs_uint32 * aserverp, afs_int32 nservers, afs_int32 acell,
            afs_stats_cmperf.srvRecordsHWM = afs_stats_cmperf.srvRecords;
     }
 
+    ReleaseWriteLock(&afs_xsrvAddr);
+
     if ( aport == AFS_FSPORT && !(newts->flags & SCAPS_KNOWN))
        afs_GetCapabilities(newts);
 
-    ReleaseWriteLock(&afs_xsrvAddr);
     ReleaseWriteLock(&afs_xserver);
     return (newts);
 }                              /* afs_GetServer */