From ad6e19331e4f3ec6566dc224f1e1c943a69c62bb Mon Sep 17 00:00:00 2001 From: Derrick Brashear Date: Mon, 15 Aug 2011 12:17:06 -0400 Subject: [PATCH] macos: fix race in afs_root same race on PutVCache in afs_root as we had on other platforms, for instance FreeBSD. use a local variable instead to avoid the race. additionally, make sure we end up with the root flagged VROOT. Change-Id: I45ac36f12565320576070fd1c6d1f99ac6db8a63 Reviewed-on: http://gerrit.openafs.org/5278 Tested-by: Derrick Brashear Reviewed-by: Derrick Brashear --- src/afs/DARWIN/osi_vfsops.c | 45 ++++++++++++++++++++++------------- src/afs/DARWIN/osi_vnodeops.c | 5 +--- src/afs/afs_vcache.c | 8 ++----- 3 files changed, 31 insertions(+), 27 deletions(-) diff --git a/src/afs/DARWIN/osi_vfsops.c b/src/afs/DARWIN/osi_vfsops.c index 919a3d0a2..d0efb8c2d 100644 --- a/src/afs/DARWIN/osi_vfsops.c +++ b/src/afs/DARWIN/osi_vfsops.c @@ -222,9 +222,10 @@ afs_root(struct mount *mp, struct vnode **vpp) int error; struct vrequest treq; struct vcache *tvp = 0; + struct vcache *gvp; + int needref=0; #ifdef AFS_DARWIN80_ENV struct ucred *cr = vfs_context_ucred(ctx); - int needref=0; #else struct proc *p = current_proc(); struct ucred _cr; @@ -236,13 +237,13 @@ afs_root(struct mount *mp, struct vnode **vpp) #endif AFS_GLOCK(); AFS_STATCNT(afs_root); + +again: if (mdata == NULL && afs_globalVp && (afs_globalVp->f.states & CStatd)) { tvp = afs_globalVp; error = 0; -#ifdef AFS_DARWIN80_ENV needref=1; -#endif } else if (mdata == (qaddr_t) - 1) { error = ENOENT; } else { @@ -266,36 +267,46 @@ afs_root(struct mount *mp, struct vnode **vpp) /* we really want this to stay around */ if (tvp) { if (mdata == NULL) { - if (afs_globalVp) { - afs_PutVCache(afs_globalVp); - afs_globalVp = NULL; - } + gvp = afs_globalVp; afs_globalVp = tvp; -#ifdef AFS_DARWIN80_ENV + if (gvp) { + afs_PutVCache(gvp); + if (tvp != afs_globalVp) { + /* someone else got there before us! */ + afs_PutVCache(tvp); + tvp = 0; + goto again; + } + } needref=1; -#endif } } else error = ENOENT; } } if (tvp) { -#ifndef AFS_DARWIN80_ENV /* DARWIN80 caller does not need a usecount reference */ +#ifndef AFS_DARWIN80_ENV /* KPI callers don't need a usecount reference */ osi_vnhold(tvp, 0); AFS_GUNLOCK(); vn_lock(AFSTOV(tvp), LK_EXCLUSIVE | LK_RETRY, p); AFS_GLOCK(); #endif + + if (needref) #ifdef AFS_DARWIN80_ENV - if (needref) /* this iocount is for the caller. the initial iocount - is for the eventual afs_PutVCache. for mdata != null, - there will not be a PutVCache, so the caller gets the - initial (from GetVCache or finalizevnode) iocount*/ - vnode_get(AFSTOV(tvp)); + /* This iocount is for the caller. the initial iocount + * is for the eventual afs_PutVCache. for mdata != null, + * there will not be a PutVCache, so the caller gets the + * initial (from GetVCache or finalizevnode) iocount + */ + vnode_get(AFSTOV(tvp)); +#else + ; #endif - if (mdata == NULL) { + + if (mdata == NULL) afs_globalVFS = mp; - } + *vpp = AFSTOV(tvp); #ifndef AFS_DARWIN80_ENV AFSTOV(tvp)->v_flag |= VROOT; diff --git a/src/afs/DARWIN/osi_vnodeops.c b/src/afs/DARWIN/osi_vnodeops.c index 108474bb3..1d8a163d6 100644 --- a/src/afs/DARWIN/osi_vnodeops.c +++ b/src/afs/DARWIN/osi_vnodeops.c @@ -2163,10 +2163,7 @@ afs_darwin_finalizevnode(struct vcache *avc, struct vnode *dvp, } ovp = AFSTOV(avc); - /* if the type changed, we still need to do a fixup, for bulkstat */ - if (!isroot && (vnode_vtype(ovp) == avc->f.m.Type && - !(avc->f.states & CDeadVnode) && vnode_vtype(ovp) != VNON)) - { + if (!(avc->f.states & CDeadVnode) && vnode_vtype(ovp) != VNON) { AFS_GUNLOCK(); #if 0 /* unsupported */ if (dvp && cnp) diff --git a/src/afs/afs_vcache.c b/src/afs/afs_vcache.c index aac212bf0..d93ed553a 100644 --- a/src/afs/afs_vcache.c +++ b/src/afs/afs_vcache.c @@ -1526,12 +1526,8 @@ afs_ProcessFS(struct vcache *avc, } } #ifdef AFS_DARWIN80_ENV - if (fixup) { - /* perform type correction on underlying vnode */ - afs_darwin_finalizevnode(avc, NULL, NULL, 0, 1); - /* re-acquire the usecount that finalizevnode disposed of */ - vnode_ref(AFSTOV(avc)); - } + if (fixup) + printf("found mistyped vnode!\n"); #endif avc->f.anyAccess = astat->AnonymousAccess; #ifdef badidea -- 2.39.5