From: Derrick Brashear Date: Mon, 15 Aug 2011 16:17:06 +0000 (-0400) Subject: macos: fix race in afs_root X-Git-Tag: openafs-devel-1_7_1~131 X-Git-Url: https://git.openafs.org/?p=openafs.git;a=commitdiff_plain;h=ad6e19331e4f3ec6566dc224f1e1c943a69c62bb 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 --- diff --git a/src/afs/DARWIN/osi_vfsops.c b/src/afs/DARWIN/osi_vfsops.c index 919a3d0..d0efb8c 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 108474b..1d8a163 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 aac212b..d93ed55 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