Change the meaning of the -fakestat switch to only enable fakestat
authorNickolai Zeldovich <kolya@mit.edu>
Mon, 7 Oct 2002 00:00:14 +0000 (00:00 +0000)
committerNickolai Zeldovich <kolya@mit.edu>
Mon, 7 Oct 2002 00:00:14 +0000 (00:00 +0000)
for cross-cell mountpoints.  The -fakestat-all switch can now be
used to enable fakestat for all mountpoints (old behavior).

src/afs/LINUX/osi_vnodeops.c
src/afs/VNOPS/afs_vnop_lookup.c
src/afs/afs_prototypes.h
src/afs/afs_util.c
src/afsd/afsd.c

index 99112c4..924fbf9 100644 (file)
@@ -776,14 +776,19 @@ static int afs_linux_revalidate(struct dentry *dp)
     struct vrequest treq;
     struct vcache *vcp = ITOAFS(dp->d_inode);
     struct vcache *rootvp = NULL;
+    struct afs_fakestat_state fakestat;
 
     AFS_GLOCK();
 
-    if (afs_fakestat_enable && vcp->mvstat == 1 && vcp->mvid &&
-       (vcp->states & CMValid) && (vcp->states & CStatd)) {
-       ObtainSharedLock(&afs_xvcache, 680);
-       rootvp = afs_FindVCache(vcp->mvid, 0, 0);
-       ReleaseSharedLock(&afs_xvcache);
+    afs_InitFakeStat(&fakestat);
+    if (vcp->mvstat == 1) {
+       afs_InitReq(&treq, credp);
+       rootvp = vcp;
+       code = afs_TryEvalFakeStat(&rootvp, &fakestat, &treq);
+       if (code) {
+           AFS_GUNLOCK();
+           return -code;
+       }
     }
 
 #ifdef AFS_LINUX24_ENV
@@ -794,14 +799,14 @@ static int afs_linux_revalidate(struct dentry *dp)
     if (vcp->states & CStatd) {
        if (*dp->d_name.name != '/' && vcp->mvstat == 2) /* root vnode */
            check_bad_parent(dp); /* check and correct mvid */
-       if (rootvp)
+       if (rootvp && rootvp != vcp)
            vcache2fakeinode(rootvp, vcp);
        else
            vcache2inode(vcp);
 #ifdef AFS_LINUX24_ENV
        unlock_kernel();
 #endif
-       if (rootvp) afs_PutVCache(rootvp);
+       afs_PutFakeStat(&fakestat);
        AFS_GUNLOCK();
        return 0;
     }
@@ -814,6 +819,7 @@ static int afs_linux_revalidate(struct dentry *dp)
 #ifdef AFS_LINUX24_ENV
     unlock_kernel();
 #endif
+    afs_PutFakeStat(&fakestat);
     AFS_GUNLOCK();
     crfree(credp);
 
index 6bde5de..74960ee 100644 (file)
@@ -260,11 +260,9 @@ 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;
@@ -281,10 +279,29 @@ int afs_EvalFakeStat_int(struct vcache **avcp, struct afs_fakestat_state *state,
     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);
index 68ac3ad..79ff4a1 100644 (file)
@@ -638,6 +638,7 @@ extern void afs_SetPrimary(register struct unixuser *au, register int aflag);
 extern char *afs_cv2string(char *ttp, afs_uint32 aval);
 extern int afs_strcasecmp(char *s1, char *s2);
 extern char *afs_strdup(char *s);
+extern char *afs_strchr(char *s, int c);
 extern void print_internet_address(char *preamble, struct srvAddr *sa,
                            char *postamble, int flag);
 extern afs_int32 afs_data_pointer_to_int32(const void *p);
index f507e8b..798d01a 100644 (file)
@@ -85,6 +85,16 @@ int afs_strcasecmp(char *s1, char *s2)
     return *s1 - *s2;
 }
 
+char *afs_strchr(char *s, int c)
+{
+    char *p;
+
+    for (p = s; *p; p++)
+       if (*p == c)
+           return p;
+    return NULL;
+}
+
 char *afs_strdup(char *s)
 {
     char *n;
index 4f9059f..5ba6687 100644 (file)
@@ -1337,6 +1337,10 @@ mainproc(as, arock)
     }
     if (as->parms[27].items) {
        /* -fakestat */
+       enable_fakestat = 2;
+    }
+    if (as->parms[28].items) {
+       /* -fakestat-all */
        enable_fakestat = 1;
     }
 
@@ -1659,7 +1663,7 @@ mainproc(as, arock)
     if (enable_fakestat) {
        if (afsd_verbose)
            printf("%s: Enabling fakestat support in kernel.\n", rn);
-       code = call_syscall(AFSOP_SET_FAKESTAT, 1);
+       code = call_syscall(AFSOP_SET_FAKESTAT, enable_fakestat);
        if (code)
            printf("%s: Error enabling fakestat support.\n", rn);
     }
@@ -1950,7 +1954,8 @@ char **argv; {
                ), "Enable AFSDB support");
     cmd_AddParm(ts, "-files_per_subdir", CMD_SINGLE, CMD_OPTIONAL, "log(2) of the number of cache files per cache subdirectory");
     cmd_AddParm(ts, "-dynroot", CMD_FLAG, CMD_OPTIONAL, "Enable dynroot support");
-    cmd_AddParm(ts, "-fakestat", CMD_FLAG, CMD_OPTIONAL, "Enable fakestat support");
+    cmd_AddParm(ts, "-fakestat", CMD_FLAG, CMD_OPTIONAL, "Enable fakestat support for cross-cell mounts");
+    cmd_AddParm(ts, "-fakestat-all", CMD_FLAG, CMD_OPTIONAL, "Enable fakestat support for all mounts");
     return (cmd_Dispatch(argc, argv));
 }