Windows: avoid vldb lookup race with network stack
authorJeffrey Altman <jaltman@your-file-system.com>
Sun, 28 Jun 2015 18:56:47 +0000 (14:56 -0400)
committerJeffrey Altman <jaltman@your-file-system.com>
Thu, 24 Sep 2015 04:20:31 +0000 (00:20 -0400)
If a VLDB query attempt occurs when there is no current cell db server
list then the VLDB query won't actually occur but the last query time
would be set.  This prevents a query from taking place again on the volume
for 60 seconds.  If the volume in question is the root.cell volume then
the redirector will be forced to return device not ready for the share
(aka \\afs\cell).

Check for a failure of cm_UpdateCell() and only set the last update time
for the volume if there was success or if the VLDB responded with volume
unknown.

Change-Id: Ic87d871feac3f2ea3d3db377854efa9dc9db3c00
Reviewed-on: http://gerrit.openafs.org/11919
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Jeffrey Altman <jaltman@your-file-system.com>

src/WINNT/afsd/cm_volume.c

index b338d60..c85107b 100644 (file)
@@ -352,8 +352,14 @@ long cm_UpdateVolumeLocation(struct cm_cell *cellp, cm_user_t *userp, cm_req_t *
         /* Do not hold the volume lock across the RPC calls */
         lock_ReleaseWrite(&volp->rw);
 
-        if (cellp->flags & CM_CELLFLAG_VLSERVER_INVALID)
-             cm_UpdateCell(cellp, 0);
+       if (cellp->flags & CM_CELLFLAG_VLSERVER_INVALID) {
+           cellp = cm_UpdateCell(cellp, 0);
+           if (cellp == NULL) {
+               lock_ObtainWrite(&volp->rw);
+               _InterlockedAnd(&volp->flags, ~CM_VOLUMEFLAG_UPDATING_VL);
+               return(CM_ERROR_NOSUCHCELL);
+           }
+       }
 
         /* now we have volume structure locked and held; make RPC to fill it */
         code = cm_GetEntryByName(cellp, volp->namep, &vldbEntry, &nvldbEntry,
@@ -707,7 +713,9 @@ long cm_UpdateVolumeLocation(struct cm_cell *cellp, cm_user_t *userp, cm_req_t *
         volp->vol[BACKVOL].state = bkNewstate;
     }
 
-    volp->lastUpdateTime = time(NULL);
+    if (code == 0 || (volp->flags & CM_VOLUMEFLAG_NOEXIST))
+       volp->lastUpdateTime = time(NULL);
+
     if (isMixed)
         _InterlockedOr(&volp->flags, CM_VOLUMEFLAG_RO_MIXED);
     else