From 5f6b59f4601e9892e082a145a75e5872818d2e06 Mon Sep 17 00:00:00 2001 From: Rainer Toebbicke Date: Tue, 15 Apr 2008 13:29:20 +0000 Subject: [PATCH] linux-fakestat-avoid-mtpt-fillin-issue-20080415 LICENSE IPL10 FIXES 93898 "It is actually the detection of a "cell" in the mount point string which triggers the (loosely consistent) fakestat handling - it's treated like a foreign cell and the mount point is never "completely evaluated", i.e. logically replaced by the root directory of the volume in question. As a result, callbacks are ignored, as they go against the directory and not the mount point." --- src/afs/LINUX/osi_vnodeops.c | 10 ++++++++-- src/afs/VNOPS/afs_vnop_lookup.c | 8 +++++--- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/afs/LINUX/osi_vnodeops.c b/src/afs/LINUX/osi_vnodeops.c index 3c7a818..6a324c8 100644 --- a/src/afs/LINUX/osi_vnodeops.c +++ b/src/afs/LINUX/osi_vnodeops.c @@ -821,8 +821,14 @@ afs_linux_dentry_revalidate(struct dentry *dp) if (vcp == afs_globalVp) goto good_dentry; - if (*dp->d_name.name != '/' && vcp->mvstat == 2) /* root vnode */ - check_bad_parent(dp); /* check and correct mvid */ + if (vcp->mvstat == 1) { /* mount point */ + if (vcp->mvid && (vcp->states & CMValid)) { + /* a mount point, not yet replaced by its directory */ + goto bad_dentry; + } + } else + if (*dp->d_name.name != '/' && vcp->mvstat == 2) /* root vnode */ + check_bad_parent(dp); /* check and correct mvid */ #ifdef notdef /* If the last looker changes, we should make sure the current diff --git a/src/afs/VNOPS/afs_vnop_lookup.c b/src/afs/VNOPS/afs_vnop_lookup.c index 59ed1f0..6389263 100644 --- a/src/afs/VNOPS/afs_vnop_lookup.c +++ b/src/afs/VNOPS/afs_vnop_lookup.c @@ -1208,6 +1208,7 @@ afs_lookup(OSI_VC_DECL(adp), char *aname, struct vcache **avcp, struct AFS_UCRED register afs_int32 code; register afs_int32 bulkcode = 0; int pass = 0, hit = 0; + int force_eval = afs_fakestat_enable ? 0 : 1; long dirCookie; extern afs_int32 afs_mariner; /*Writing activity to log? */ afs_hyper_t versionNo; @@ -1596,8 +1597,6 @@ afs_lookup(OSI_VC_DECL(adp), char *aname, struct vcache **avcp, struct AFS_UCRED } /* sub-block just to reduce stack usage */ if (tvc) { - int force_eval = afs_fakestat_enable ? 0 : 1; - if (adp->states & CForeign) tvc->states |= CForeign; tvc->parentVnode = adp->fid.Fid.Vnode; @@ -1618,6 +1617,9 @@ afs_lookup(OSI_VC_DECL(adp), char *aname, struct vcache **avcp, struct AFS_UCRED force_eval = 1; ReleaseReadLock(&tvc->lock); } + if (tvc->mvstat == 1 && (tvc->states & CMValid) && tvc->mvid != NULL) + force_eval = 1; /* This is now almost for free, get it correct */ + #if defined(UKERNEL) && defined(AFS_WEB_ENHANCEMENTS) if (!(flags & AFS_LOOKUP_NOEVAL)) /* don't eval mount points */ @@ -1743,7 +1745,7 @@ afs_lookup(OSI_VC_DECL(adp), char *aname, struct vcache **avcp, struct AFS_UCRED * rather than the vc of the mount point itself. we can still find the * mount point's vc in the vcache by its fid. */ #endif /* UKERNEL && AFS_WEB_ENHANCEMENTS */ - if (!hit) { + if (!hit && force_eval) { osi_dnlc_enter(adp, aname, tvc, &versionNo); } else { #ifdef AFS_LINUX20_ENV -- 1.9.4