afs: make sure to call afs_Analyze after afs_Conn 88/13288/3
authorMichael Meffie <mmeffie@sinenomine.net>
Fri, 16 Mar 2018 14:25:18 +0000 (09:25 -0500)
committerBenjamin Kaduk <kaduk@mit.edu>
Sat, 6 Oct 2018 20:06:20 +0000 (16:06 -0400)
The afs_Conn function is used to pick a connection for a given RPC. The
RPC is normally wrapped within a do-while loop which calls afs_Analyze
to handle the RPC code and manage the server connection references.
Among other things, afs_Analyze can mark the server as down, blacklist
idle servers, etc.

There are some special cases in which we break out of this do-while loop
early, by putting the connection reference given by afs_Conn and then
jumping out of the loop.

In these cases, be sure to call afs_Analyze to put the server connection
we got from afs_Conn, and to handle the RPC return code, possibly
marking the server as down or blacklisted.

Change-Id: Ic2c43f20d153376b93d79bbb5145914f8e478957
Reviewed-on: https://gerrit.openafs.org/13288
Reviewed-by: Andrew Deason <adeason@sinenomine.net>
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>

src/afs/afs_bypasscache.c
src/afs/afs_dcache.c

index 847eaf0..64da1ed 100644 (file)
@@ -614,7 +614,9 @@ afs_PrefetchNoCache(struct vcache *avc,
            } else {
                afs_warn("BYPASS: StartRXAFS_FetchData failed: %d\n", code);
                unlock_and_release_pages(auio);
-               afs_PutConn(tc, rxconn, SHARED_LOCK);
+               (void)afs_Analyze(tc, rxconn, code, &avc->f.fid, areq,
+                                 AFS_STATS_FS_RPCIDX_FETCHDATA,
+                                 SHARED_LOCK, NULL);
                goto done;
            }
            if (code == 0) {
@@ -629,6 +631,9 @@ afs_PrefetchNoCache(struct vcache *avc,
            afs_warn("BYPASS: No connection.\n");
            code = -1;
            unlock_and_release_pages(auio);
+           (void)afs_Analyze(tc, rxconn, code, &avc->f.fid, areq,
+                             AFS_STATS_FS_RPCIDX_FETCHDATA,
+                             SHARED_LOCK, NULL);
            goto done;
        }
     } while (afs_Analyze(tc, rxconn, code, &avc->f.fid, areq,
index 64f88a9..4b93915 100644 (file)
@@ -2489,13 +2489,18 @@ afs_GetDCache(struct vcache *avc, afs_size_t abyte,
                        ReleaseWriteLock(&tdc->lock);
                        afs_PutDCache(tdc);
                        tdc = 0;
-                       ReleaseReadLock(&avc->lock);
 
-                       if (tc) {
-                           /* If we have a connection, we must put it back,
-                            * since afs_Analyze will not be called here. */
-                           afs_PutConn(tc, rxconn, SHARED_LOCK);
-                       }
+                       /*
+                        * Call afs_Analyze to manage the connection references
+                        * and handle the error code (possibly mark servers
+                        * down, etc). We are going to retry getting the
+                        * dcache regardless, so we just ignore the retry hint
+                        * returned by afs_Analyze on this call.
+                        */
+                       (void)afs_Analyze(tc, rxconn, code, &avc->f.fid, areq,
+                                         AFS_STATS_FS_RPCIDX_FETCHDATA, SHARED_LOCK, NULL);
+
+                       ReleaseReadLock(&avc->lock);
 
                        slowPass = 1;
                        goto RetryGetDCache;