From: Derrick Brashear Date: Mon, 14 Jun 2004 09:36:09 +0000 (+0000) Subject: darwin-updates-20040613 X-Git-Tag: openafs-devel-1_3_65~57 X-Git-Url: http://git.openafs.org/?p=openafs.git;a=commitdiff_plain;h=e81615d0f1ca357eb5e44a0c3b54046798702a8f darwin-updates-20040613 complain if TryReclaim gets a vnode which is on the inactive list ==================== This delta was composed from multiple commits as part of the CVS->Git migration. The checkin message with each commit was inconsistent. The following are the additional commit messages. ==================== be willing to instantiate a ubc in our lookup vop (rename needs this so the followup vget doesn't get a vnode with no ubc) refuse to instantiate a ubc if VORECLAIM is set rework rename 2 links to same vnode case. (yes, you can have hard links in AFS) ==================== drop the parent directory ref and remove name from the kernel name cache when recycling a vnode. --- diff --git a/src/afs/DARWIN/osi_vm.c b/src/afs/DARWIN/osi_vm.c index df1f8e5..0c2b1a1 100644 --- a/src/afs/DARWIN/osi_vm.c +++ b/src/afs/DARWIN/osi_vm.c @@ -61,6 +61,30 @@ osi_VM_FlushVCache(struct vcache *avc, int *slept) ubc_release(vp); ubc_info_free(vp); } +#else + /* This is literally clean_up_name_parent_ptrs() */ + /* Critical to clean up any state attached to the vnode here since it's + being recycled, and we're not letting refcnt drop to 0 to trigger + normal recycling. */ + if (VNAME(vp) || VPARENT(vp)) { + char *tmp1; + struct vnode *tmp2; + + /* do it this way so we don't block before clearing + these fields. */ + tmp1 = VNAME(vp); + tmp2 = VPARENT(vp); + VNAME(vp) = NULL; + VPARENT(vp) = NULL; + + if (tmp1) { + remove_name(tmp1); + } + + if (tmp2) { + vrele(tmp2); + } + } #endif AFS_GLOCK(); @@ -178,6 +202,12 @@ osi_VM_TryReclaim(struct vcache *avc, int *slept) AFS_RELE(vp); return; } + if (ISSET(vp->v_flag, VUINACTIVE)) { + simple_unlock(&vp->v_interlock); + AFS_RELE(vp); + printf("vnode %x still inactive!", vp); + return; + } #ifdef AFS_DARWIN14_ENV if (vp->v_ubcinfo->ui_refcount > 1 || vp->v_ubcinfo->ui_mapped) { simple_unlock(&vp->v_interlock); diff --git a/src/afs/DARWIN/osi_vnodeops.c b/src/afs/DARWIN/osi_vnodeops.c index ca2cf2c..9798e03 100644 --- a/src/afs/DARWIN/osi_vnodeops.c +++ b/src/afs/DARWIN/osi_vnodeops.c @@ -188,6 +188,16 @@ afs_vop_lookup(ap) vp = AFSTOV(vcp); /* always get a node if no error */ vp->v_vfsp = dvp->v_vfsp; + if (UBCINFOMISSING(vp) || + UBCINFORECLAIMED(vp)) { +#ifdef AFS_DARWIN14_ENV + if (UBCINFORECLAIMED(vp) && ISSET(vp->v_flag, (VXLOCK|VORECLAIM))) { + DROPNAME(); + return (ENXIO); + } else +#endif + ubc_info_init(vp); + } /* The parent directory comes in locked. We unlock it on return * unless the caller wants it left locked. * we also always return the vnode locked. */ @@ -253,8 +263,17 @@ afs_vop_create(ap) *ap->a_vpp = AFSTOV(vcp); (*ap->a_vpp)->v_vfsp = dvp->v_vfsp; vn_lock(*ap->a_vpp, LK_EXCLUSIVE | LK_RETRY, p); - if (UBCINFOMISSING(*ap->a_vpp) || UBCINFORECLAIMED(*ap->a_vpp)) - ubc_info_init(*ap->a_vpp); + if (UBCINFOMISSING(*ap->a_vpp) || UBCINFORECLAIMED(*ap->a_vpp)) { +#ifdef AFS_DARWIN14_ENV + if (UBCINFORECLAIMED(*ap->a_vpp) && ISSET((*ap->a_vpp)->v_flag, + (VXLOCK|VORECLAIM))) { + vput(dvp); + DROPNAME(); + return (ENXIO); + } else +#endif + ubc_info_init(*ap->a_vpp); + } } else *ap->a_vpp = 0; @@ -957,8 +976,22 @@ afs_vop_rename(ap) if ((fcnp->cn_flags & SAVESTART) == 0) panic("afs_rename: lost from startdir"); fcnp->cn_nameiop = DELETE; - (void)relookup(fdvp, &fvp, fcnp); - return (VOP_REMOVE(fdvp, fvp, fcnp)); + + VREF(fdvp); + error=relookup(fdvp, &fvp, fcnp); + if (error == 0) + vrele(fdvp); + if (fvp == NULL) { + return (ENOENT); + } + + error=VOP_REMOVE(fdvp, fvp, fcnp); + if (fdvp == fvp) + vrele(fdvp); + else + vput(fdvp); + vput(fvp); + return (error); } if (error = vn_lock(fvp, LK_EXCLUSIVE, p)) goto abortit;