Change the meaning of the -fakestat switch to only enable fakestat
[openafs.git] / src / afs / VNOPS / afs_vnop_lookup.c
index 11d5430..74960ee 100644 (file)
@@ -105,7 +105,7 @@ int EvalMountPoint(register struct vcache *avc, struct vcache *advc,
     struct VenusFid tfid;
     struct cell *tcell;
     char   *cpos, *volnamep;
-    char   type, buf[128];
+    char   type, *buf;
     afs_int32  prefetchRO;          /* 1=>No  2=>Yes */
     afs_int32  mtptCell, assocCell, hac=0;
     afs_int32  samecell, roname, len;
@@ -132,10 +132,10 @@ int EvalMountPoint(register struct vcache *avc, struct vcache *advc,
     }
     if (!tcell) return ENODEV;
 
-    mtptCell = tcell->cell;               /* The cell for the mountpoint */
+    mtptCell = tcell->cellNum;             /* The cell for the mountpoint */
     if (tcell->lcellp) {
-       hac = 1;                           /* has associated cell */
-       assocCell = tcell->lcellp->cell;   /* The associated cell */
+       hac = 1;                             /* has associated cell */
+       assocCell = tcell->lcellp->cellNum;  /* The associated cell */
     }
     afs_PutCell(tcell, READ_LOCK);         
 
@@ -174,15 +174,18 @@ int EvalMountPoint(register struct vcache *avc, struct vcache *advc,
      * Don't know why we do this. Would have still found it in above call - jpm.
      */
     if (!tvp && (prefetchRO == 2)) {
-       strcpy(buf, volnamep);
-       afs_strcat(buf, ".readonly");
+       buf = (char *)osi_AllocSmallSpace(strlen(volnamep)+10);
 
-       tvp = afs_GetVolumeByName(buf, mtptCell, 1, areq, WRITE_LOCK);
+       strcpy(buf, volnamep);
+       afs_strcat(buf, ".readonly");
 
-       /* Try the associated linked cell if failed */
-       if (!tvp && hac && areq->volumeError) {
-         tvp = afs_GetVolumeByName(buf, assocCell, 1, areq, WRITE_LOCK);
-       }
+       tvp = afs_GetVolumeByName(buf, mtptCell, 1, areq, WRITE_LOCK);
+       
+       /* Try the associated linked cell if failed */
+       if (!tvp && hac && areq->volumeError) {
+           tvp = afs_GetVolumeByName(buf, assocCell, 1, areq, WRITE_LOCK);
+       }
+       osi_FreeSmallSpace(buf);
     }
   
     if (!tvp) return ENODEV;       /* Couldn't find the volume */
@@ -244,6 +247,9 @@ int EvalMountPoint(register struct vcache *avc, struct vcache *advc,
  */
 void afs_InitFakeStat(struct afs_fakestat_state *state)
 {
+    if (!afs_fakestat_enable)
+       return;
+
     state->valid = 1;
     state->did_eval = 0;
     state->need_release = 0;
@@ -254,29 +260,48 @@ void afs_InitFakeStat(struct afs_fakestat_state *state)
  *
  * The actual implementation of afs_EvalFakeStat and afs_TryEvalFakeStat,
  * which is called by those wrapper functions.
- *
- * Only issues RPCs if canblock is non-zero.
  */
-int afs_EvalFakeStat_int(struct vcache **avcp, struct afs_fakestat_state *state,
-       struct vrequest *areq, int canblock)
+static int afs_EvalFakeStat_int(struct vcache **avcp,
+       struct afs_fakestat_state *state, struct vrequest *areq, int canblock)
 {
     struct vcache *tvc, *root_vp;
     struct volume *tvolp = NULL;
     int code = 0;
 
+    if (!afs_fakestat_enable)
+       return 0;
+
     osi_Assert(state->valid == 1);
     osi_Assert(state->did_eval == 0);
     state->did_eval = 1;
-    if (!afs_fakestat_enable)
-       return 0;
+
     tvc = *avcp;
     if (tvc->mvstat != 1)
        return 0;
 
-    /* Is the call to VerifyVCache really necessary? */
     code = afs_VerifyVCache(tvc, areq);
     if (code)
        goto done;
+
+    if (afs_fakestat_enable == 2 && !canblock) {
+       ObtainSharedLock(&tvc->lock, 680);
+       if (!tvc->linkData) {
+           UpgradeSToWLock(&tvc->lock, 681);
+           code = afs_HandleLink(tvc, areq);
+           if (code) {
+               ReleaseWriteLock(&tvc->lock);
+               goto done;
+           }
+           ConvertWToRLock(&tvc->lock);
+       } else {
+           ConvertSToRLock(&tvc->lock);
+       }
+
+       if (!afs_strchr(tvc->linkData, ':'))
+           canblock = 1;
+       ReleaseReadLock(&tvc->lock);
+    }
+
     if (canblock) {
        ObtainWriteLock(&tvc->lock, 599);
        code = EvalMountPoint(tvc, NULL, &tvolp, areq);
@@ -378,6 +403,9 @@ int afs_TryEvalFakeStat(struct vcache **avcp, struct afs_fakestat_state *state,
  */
 void afs_PutFakeStat(struct afs_fakestat_state *state)
 {
+    if (!afs_fakestat_enable)
+       return;
+
     osi_Assert(state->valid == 1);
     if (state->need_release)
        afs_PutVCache(state->root_vp);
@@ -1296,20 +1324,14 @@ afs_lookup(adp, aname, avcp, acred)
     afs_PutDCache(tdc);
 
     if (code == ENOENT && afs_IsDynroot(adp) && dynrootRetry) {
-       struct cell *tcell;
-
        ReleaseReadLock(&adp->lock);
        dynrootRetry = 0;
-       if (*tname == '.')
-           tcell = afs_GetCellByName(tname + 1, READ_LOCK);
+       if (tname[0] == '.')
+           afs_LookupAFSDB(tname + 1);
        else
-           tcell = afs_GetCellByName(tname, READ_LOCK);
-       if (tcell) {
-           afs_PutCell(tcell, READ_LOCK);
-           afs_RefreshDynroot();
-           if (tname != aname && tname) osi_FreeLargeSpace(tname);
-           goto redo;
-       }
+           afs_LookupAFSDB(tname);
+       if (tname && tname != aname) osi_FreeLargeSpace(tname);
+       goto redo;
     } else {
        ReleaseReadLock(&adp->lock);
     }