From: Derrick Brashear Date: Tue, 7 Oct 2008 20:00:31 +0000 (+0000) Subject: linux-d-reval-rewrite-mtpts-when-fakestat-enabled-20081007 X-Git-Tag: openafs-devel-1_5_61~775 X-Git-Url: http://git.openafs.org/?p=openafs.git;a=commitdiff_plain;h=b3bf4b89e345b991984a416d97e3f9aeacc0e159 linux-d-reval-rewrite-mtpts-when-fakestat-enabled-20081007 LICENSE IPL10 FIXES 113558 avoid case where revalidate saw a mountpoint which hadn't been rewritten yet and failed to handle it, exposing ENOENT where the entry existed. --- diff --git a/src/afs/LINUX/osi_vnodeops.c b/src/afs/LINUX/osi_vnodeops.c index eb57bb9..60b11ca 100644 --- a/src/afs/LINUX/osi_vnodeops.c +++ b/src/afs/LINUX/osi_vnodeops.c @@ -876,11 +876,13 @@ afs_linux_dentry_revalidate(struct dentry *dp) cred_t *credp = NULL; struct vcache *vcp, *pvcp, *tvc = NULL; int valid; + struct afs_fakestat_state fakestate; #ifdef AFS_LINUX24_ENV maybe_lock_kernel(); #endif AFS_GLOCK(); + afs_InitFakeStat(&fakestate); if (dp->d_inode) { @@ -892,8 +894,28 @@ afs_linux_dentry_revalidate(struct dentry *dp) if (vcp->mvstat == 1) { /* mount point */ if (vcp->mvid && (vcp->states & CMValid)) { - /* a mount point, not yet replaced by its directory */ - goto bad_dentry; + int tryEvalOnly = 0; + int code = 0; + struct vrequest treq; + + credp = crref(); + code = afs_InitReq(&treq, credp); + if ( +#ifdef AFS_DARWIN_ENV + (strcmp(dp->d_name.name, ".DS_Store") == 0) || + (strcmp(dp->d_name.name, "Contents") == 0) || +#endif + (strcmp(dp->d_name.name, ".directory") == 0)) { + tryEvalOnly = 1; + } + if (tryEvalOnly) + code = afs_TryEvalFakeStat(&vcp, &fakestate, &treq); + else + code = afs_EvalFakeStat(&vcp, &fakestate, &treq); + if ((tryEvalOnly && vcp->mvstat == 1) || code) { + /* a mount point, not yet replaced by its directory */ + goto bad_dentry; + } } } else if (*dp->d_name.name != '/' && vcp->mvstat == 2) /* root vnode */ @@ -957,6 +979,7 @@ afs_linux_dentry_revalidate(struct dentry *dp) /* Clean up */ if (tvc) afs_PutVCache(tvc); + afs_PutFakeStat(&fakestate); AFS_GUNLOCK(); if (credp) crfree(credp); @@ -971,7 +994,10 @@ afs_linux_dentry_revalidate(struct dentry *dp) return valid; bad_dentry: - valid = 0; + if (have_submounts(dp)) + valid = 1; + else + valid = 0; goto done; }