From 55c20de02a2a1c51df04ac1d397fdc25f5668b9c Mon Sep 17 00:00:00 2001 From: Nickolai Zeldovich Date: Thu, 14 Nov 2002 21:03:57 +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). (cherry picked from commit f0c7fe9ee1d07d50fe9f53598f36d42e365f0d89) --- src/afs/LINUX/osi_vnodeops.c | 20 +++++++++++++------- src/afs/VNOPS/afs_vnop_lookup.c | 31 ++++++++++++++++++++++--------- src/afs/afs_prototypes.h | 1 + src/afs/afs_util.c | 10 ++++++++++ src/afsd/afsd.c | 9 +++++++-- 5 files changed, 53 insertions(+), 18 deletions(-) diff --git a/src/afs/LINUX/osi_vnodeops.c b/src/afs/LINUX/osi_vnodeops.c index e58af0ac7..30a2eaf47 100644 --- a/src/afs/LINUX/osi_vnodeops.c +++ b/src/afs/LINUX/osi_vnodeops.c @@ -675,14 +675,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, 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 @@ -693,14 +698,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; } @@ -713,6 +718,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 7450763da..0a57b58a8 100644 --- a/src/afs/VNOPS/afs_vnop_lookup.c +++ b/src/afs/VNOPS/afs_vnop_lookup.c @@ -265,15 +265,9 @@ afs_InitFakeStat(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. */ -static int -afs_EvalFakeStat_int(avcp, state, areq, canblock) - struct vcache **avcp; - struct afs_fakestat_state *state; - struct vrequest *areq; - int canblock; +static int afs_EvalFakeStat_int(stricr vcache **avcp, + struct afs_fakestat_state *state, struct vrequest *areq, int canblock) { struct vcache *tvc, *root_vp; struct volume *tvolp = NULL; @@ -288,10 +282,29 @@ afs_EvalFakeStat_int(avcp, state, areq, canblock) 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 8c7fb39c4..2bbfc9eb8 100644 --- a/src/afs/afs_prototypes.h +++ b/src/afs/afs_prototypes.h @@ -84,6 +84,7 @@ extern void afs_GCPAGs_perproc_func(AFS_PROC *pproc); /* afs_util.c */ extern char *afs_cv2string(char *ttp, afs_uint32 aval); +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 ddc9e9542..e76146072 100644 --- a/src/afs/afs_util.c +++ b/src/afs/afs_util.c @@ -71,6 +71,16 @@ char *afs_cv2string(char *ttp, afs_uint32 aval) } /*afs_cv2string*/ +char *afs_strchr(char *s, int c) +{ + char *p; + + for (p = s; *p; p++) + if (*p == c) + return p; + return NULL; +} + void print_internet_address(char *preamble, struct srvAddr *sa, char *postamble, int flag) { diff --git a/src/afsd/afsd.c b/src/afsd/afsd.c index de1a7a1b4..d2921d532 100644 --- a/src/afsd/afsd.c +++ b/src/afsd/afsd.c @@ -1335,6 +1335,10 @@ mainproc(as, arock) } if (as->parms[27].items) { /* -fakestat */ + enable_fakestat = 2; + } + if (as->parms[28].items) { + /* -fakestat-all */ enable_fakestat = 1; } @@ -1579,7 +1583,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); } @@ -1937,7 +1941,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)); } -- 2.39.5