From 217c516c1ba2634560ccba50a246aeea7d097f29 Mon Sep 17 00:00:00 2001 From: Nickolai Zeldovich Date: Thu, 14 Nov 2002 21:24:30 +0000 Subject: [PATCH] A better way to do cross-cell-only fakestat, which should also avoid problems with Linux's attribute validation. (cherry picked from commit 2d182a7fc1aa17bce1f63164944995663f567c12) --- src/afs/LINUX/osi_vnodeops.c | 20 +++++-------- src/afs/VNOPS/afs_vnop_lookup.c | 50 ++++++++++++++++----------------- 2 files changed, 32 insertions(+), 38 deletions(-) diff --git a/src/afs/LINUX/osi_vnodeops.c b/src/afs/LINUX/osi_vnodeops.c index 30a2eaf47..e58af0ac7 100644 --- a/src/afs/LINUX/osi_vnodeops.c +++ b/src/afs/LINUX/osi_vnodeops.c @@ -675,19 +675,14 @@ 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(); - 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; - } + 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); } #ifdef AFS_LINUX24_ENV @@ -698,14 +693,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 && rootvp != vcp) + if (rootvp) vcache2fakeinode(rootvp, vcp); else vcache2inode(vcp); #ifdef AFS_LINUX24_ENV unlock_kernel(); #endif - afs_PutFakeStat(&fakestat); + if (rootvp) afs_PutVCache(rootvp); AFS_GUNLOCK(); return 0; } @@ -718,7 +713,6 @@ 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 0a57b58a8..0c393fb32 100644 --- a/src/afs/VNOPS/afs_vnop_lookup.c +++ b/src/afs/VNOPS/afs_vnop_lookup.c @@ -54,7 +54,7 @@ extern struct inode_operations afs_symlink_iops, afs_dir_iops; afs_int32 afs_bulkStatsDone; static int bulkStatCounter = 0; /* counter for bulk stat seq. numbers */ -int afs_fakestat_enable = 0; +int afs_fakestat_enable = 0; /* 1: fakestat-all, 2: fakestat-crosscell */ /* this would be faster if it did comparison as int32word, but would be @@ -265,9 +265,11 @@ 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(stricr vcache **avcp, - struct afs_fakestat_state *state, struct vrequest *areq, int canblock) +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; @@ -282,29 +284,10 @@ static int afs_EvalFakeStat_int(stricr vcache **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); @@ -1413,17 +1396,34 @@ afs_lookup(adp, aname, avcp, acred) } /* sub-block just to reduce stack usage */ if (tvc) { - if (adp->states & CForeign) + int force_eval = afs_fakestat_enable ? 0 : 1; + + if (adp->states & CForeign) tvc->states |= CForeign; tvc->parentVnode = adp->fid.Fid.Vnode; tvc->parentUnique = adp->fid.Fid.Unique; tvc->states &= ~CBulkStat; + if (afs_fakestat_enable == 2 && tvc->mvstat == 1) { + ObtainSharedLock(&tvc->lock, 680); + if (!tvc->linkData) { + UpgradeSToWLock(&tvc->lock, 681); + code = afs_HandleLink(tvc, &treq); + ConvertWToRLock(&tvc->lock); + } else { + ConvertSToRLock(&tvc->lock); + code = 0; + } + if (!code && !strchr(tvc->linkData, ':')) + force_eval = 1; + ReleaseReadLock(&tvc->lock); + } + #if defined(UKERNEL) && defined(AFS_WEB_ENHANCEMENTS) if (!(flags & AFS_LOOKUP_NOEVAL)) /* don't eval mount points */ #endif /* UKERNEL && AFS_WEB_ENHANCEMENTS */ - if (!afs_fakestat_enable && tvc->mvstat == 1) { + if (tvc->mvstat == 1 && force_eval) { /* a mt point, possibly unevaluated */ struct volume *tvolp; -- 2.39.5