From f0c7fe9ee1d07d50fe9f53598f36d42e365f0d89 Mon Sep 17 00:00:00 2001 From: Nickolai Zeldovich Date: Mon, 7 Oct 2002 00:00:14 +0000 Subject: [PATCH] Change the meaning of the -fakestat switch to only enable fakestat 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 | 20 +++++++++++++------- src/afs/VNOPS/afs_vnop_lookup.c | 27 ++++++++++++++++++++++----- src/afs/afs_prototypes.h | 1 + src/afs/afs_util.c | 10 ++++++++++ src/afsd/afsd.c | 9 +++++++-- 5 files changed, 53 insertions(+), 14 deletions(-) diff --git a/src/afs/LINUX/osi_vnodeops.c b/src/afs/LINUX/osi_vnodeops.c index 99112c4..924fbf9 100644 --- a/src/afs/LINUX/osi_vnodeops.c +++ b/src/afs/LINUX/osi_vnodeops.c @@ -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); diff --git a/src/afs/VNOPS/afs_vnop_lookup.c b/src/afs/VNOPS/afs_vnop_lookup.c index 6bde5de..74960ee 100644 --- a/src/afs/VNOPS/afs_vnop_lookup.c +++ b/src/afs/VNOPS/afs_vnop_lookup.c @@ -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); diff --git a/src/afs/afs_prototypes.h b/src/afs/afs_prototypes.h index 68ac3ad..79ff4a1 100644 --- a/src/afs/afs_prototypes.h +++ b/src/afs/afs_prototypes.h @@ -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); diff --git a/src/afs/afs_util.c b/src/afs/afs_util.c index f507e8b..798d01a 100644 --- a/src/afs/afs_util.c +++ b/src/afs/afs_util.c @@ -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; diff --git a/src/afsd/afsd.c b/src/afsd/afsd.c index 4f9059f..5ba6687 100644 --- a/src/afsd/afsd.c +++ b/src/afsd/afsd.c @@ -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)); } -- 1.9.4