From 74e6409d65a906cb80f3ca659e56f813a5500531 Mon Sep 17 00:00:00 2001 From: Derrick Brashear Date: Wed, 23 Jun 2004 23:25:06 +0000 Subject: [PATCH] darwin-updates-20040623 this should be switched to use the freebsd style getnewvnode perhaps it will be --- src/afs/DARWIN/osi_vm.c | 116 ++++++++++++++++++++++--------- src/afs/DARWIN/osi_vnodeops.c | 14 +++- src/afs/VNOPS/afs_vnop_remove.c | 25 ++++++- src/afs/afs_vcache.c | 38 ++++++++-- src/config/param.ppc_darwin_12.h | 2 + src/config/param.ppc_darwin_13.h | 2 + src/config/param.ppc_darwin_14.h | 2 + src/config/param.ppc_darwin_70.h | 2 + 8 files changed, 162 insertions(+), 39 deletions(-) diff --git a/src/afs/DARWIN/osi_vm.c b/src/afs/DARWIN/osi_vm.c index 0c2b1a196..7f9cae4eb 100644 --- a/src/afs/DARWIN/osi_vm.c +++ b/src/afs/DARWIN/osi_vm.c @@ -42,7 +42,7 @@ osi_VM_FlushVCache(struct vcache *avc, int *slept) if (UBCINFOEXISTS(vp)) return EBUSY; #endif - if (avc->vrefCount) + if (avc->vrefCount > DARWIN_REFBASE) return EBUSY; if (avc->opens) @@ -189,6 +189,9 @@ osi_VM_TryReclaim(struct vcache *avc, int *slept) struct proc *p = current_proc(); struct vnode *vp = AFSTOV(avc); void *obj; +#ifdef AFS_DARWIN14_ENV + int didhold; +#endif if (slept) *slept = 0; @@ -197,7 +200,7 @@ osi_VM_TryReclaim(struct vcache *avc, int *slept) AFS_RELE(vp); return; } - if (!UBCINFOEXISTS(vp) || vp->v_count != 2) { + if (!UBCINFOEXISTS(vp) || vp->v_usecount != 2+DARWIN_REFBASE) { simple_unlock(&vp->v_interlock); AFS_RELE(vp); return; @@ -214,6 +217,11 @@ osi_VM_TryReclaim(struct vcache *avc, int *slept) AFS_RELE(vp); return; } + if (ISSET(vp->v_flag, VORECLAIM)) { + simple_unlock(&vp->v_interlock); + AFS_RELE(vp); + return; + } #else if (vp->v_ubcinfo->ui_holdcnt) { simple_unlock(&vp->v_interlock); @@ -228,7 +236,9 @@ osi_VM_TryReclaim(struct vcache *avc, int *slept) return; } +#ifndef AFS_DARWIN14_ENV vp->v_usecount--; /* we want the usecount to be 1 */ +#endif if (slept) { ReleaseWriteLock(&afs_xvcache); @@ -246,47 +256,91 @@ osi_VM_TryReclaim(struct vcache *avc, int *slept) #endif if (ubc_issetflags(vp, UI_HASOBJREF)) printf("ubc_release didn't release the reference?!\n"); - } else if (!vn_lock(vp, LK_EXCLUSIVE | LK_INTERLOCK, current_proc())) { + } else { #ifdef AFS_DARWIN14_ENV - obj = ubc_getobject(vp, UBC_HOLDOBJECT); + SET(vp->v_flag, VORECLAIM); +#endif + if (!vn_lock(vp, LK_EXCLUSIVE|LK_INTERLOCK,current_proc())) { +#ifdef AFS_DARWIN14_ENV + obj = ubc_getobject(vp,UBC_HOLDOBJECT); + if ((didhold = ubc_hold(vp))) + (void)ubc_clean(vp, 0); #else #ifdef AFS_DARWIN13_ENV - obj = ubc_getobject(vp, (UBC_NOREACTIVATE | UBC_HOLDOBJECT)); + obj = ubc_getobject(vp,(UBC_NOREACTIVATE|UBC_HOLDOBJECT)); +#else + obj = ubc_getobject(vp); +#endif + (void)ubc_clean(vp, 1); +#endif + vinvalbuf(vp, V_SAVE, &afs_osi_cred, p, 0, 0); + if (vp->v_usecount == +#ifdef AFS_DARWIN14_ENV + 2 + DARWIN_REFBASE #else - obj = ubc_getobject(vp); + 1 #endif + ) + VOP_INACTIVE(vp, p); + else + VOP_UNLOCK(vp, 0, p); +#ifdef AFS_DARWIN14_ENV + if (didhold) + ubc_rele(vp); #endif - (void)ubc_clean(vp, 1); - vinvalbuf(vp, V_SAVE, &afs_osi_cred, p, 0, 0); - if (vp->v_usecount == 1) - VOP_INACTIVE(vp, p); - else - VOP_UNLOCK(vp, 0, p); - if (obj) { - if (ISSET(vp->v_flag, VTERMINATE)) - panic("afs_vnreclaim: already teminating"); - SET(vp->v_flag, VTERMINATE); - memory_object_destroy(obj, 0); - while (ISSET(vp->v_flag, VTERMINATE)) { - SET(vp->v_flag, VTERMWANT); - tsleep((caddr_t) & vp->v_ubcinfo, PINOD, "afs_vnreclaim", 0); + if (obj) { + if (ISSET(vp->v_flag, VTERMINATE)) + panic("afs_vnreclaim: already teminating"); + SET(vp->v_flag, VTERMINATE); + memory_object_destroy(obj, 0); + while (ISSET(vp->v_flag, VTERMINATE)) { + SET(vp->v_flag, VTERMWANT); + tsleep((caddr_t)&vp->v_ubcinfo, PINOD, "afs_vnreclaim", 0); + } } - } - } else { - if (simple_lock_try(&vp->v_interlock)) - panic("afs_vnreclaim: slept, but did no work :("); - if (UBCINFOEXISTS(vp) && vp->v_count == 1) { - vp->v_usecount++; - simple_unlock(&vp->v_interlock); - VN_RELE(vp); - } else +#ifdef AFS_DARWIN14_ENV + simple_lock(&vp->v_interlock); + CLR(vp->v_flag, VORECLAIM); + if (ISSET((vp)->v_flag, VXWANT)) { + CLR((vp)->v_flag, VXWANT); + wakeup((caddr_t)(vp)); + } + vp->v_usecount--; simple_unlock(&vp->v_interlock); +#endif + } else { +#ifdef AFS_DARWIN14_ENV + CLR(vp->v_flag, VORECLAIM); +#endif + if (simple_lock_try(&vp->v_interlock)) + panic("afs_vnreclaim: slept, but did no work :("); + if (UBCINFOEXISTS(vp) && vp->v_count == DARWIN_REFBASE + +#ifdef AFS_DARWIN14_ENV + 2 +#else + 1 +#endif + ) { +#ifndef AFS_DARWIN14_ENV + /* We left the refcount high in 1.4 */ + vp->v_usecount++; +#endif + simple_unlock(&vp->v_interlock); + VN_RELE(vp); + } else { +#ifdef AFS_DARWIN14_ENV + /* We left the refcount high in 1.4 */ + vp->v_usecount--; +#endif + simple_unlock(&vp->v_interlock); + } + } } AFS_GLOCK(); if (slept) - ObtainWriteLock(&afs_xvcache, 175); + ObtainWriteLock(&afs_xvcache,175); else - ObtainReadLock(&afs_xvcache); + ObtainReadLock(&afs_xvcache); } void diff --git a/src/afs/DARWIN/osi_vnodeops.c b/src/afs/DARWIN/osi_vnodeops.c index 9798e03cc..5413cf6f7 100644 --- a/src/afs/DARWIN/osi_vnodeops.c +++ b/src/afs/DARWIN/osi_vnodeops.c @@ -371,6 +371,17 @@ afs_vop_close(ap) printf("afs: WARNING: ui_refcount panic averted\n"); } } + if (UBCINFOMISSING(ap->a_vp) || + UBCINFORECLAIMED(ap->a_vp)) { + if (UBCINFORECLAIMED(ap->a_vp) && ISSET(ap->a_vp->v_flag, + (VXLOCK|VORECLAIM))) { + printf("no ubc for %x in close, reclaim set\n", ap->a_vp); + return (ENXIO); + } else { + printf("no ubc for %x in close, put back\n", ap->a_vp); + ubc_info_init(ap->a_vp); + } + } #endif return code; @@ -852,7 +863,8 @@ afs_vop_remove(ap) cache_purge(vp); if (!error && UBCINFOEXISTS(vp)) { #ifdef AFS_DARWIN14_ENV - (void)ubc_uncache(vp); + /* If crashes continue in ubc_hold, comment this out */ + /* (void)ubc_uncache(vp);*/ #else int wasmapped = ubc_issetflags(vp, UI_WASMAPPED); int hasobjref = ubc_issetflags(vp, UI_HASOBJREF); diff --git a/src/afs/VNOPS/afs_vnop_remove.c b/src/afs/VNOPS/afs_vnop_remove.c index 08473340b..447bb18ba 100644 --- a/src/afs/VNOPS/afs_vnop_remove.c +++ b/src/afs/VNOPS/afs_vnop_remove.c @@ -402,11 +402,16 @@ OSI_VC_DECL(adp); Ttvcr = VREFCOUNT(tvc); #ifdef AFS_AIX_ENV if (tvc && (VREFCOUNT(tvc) > 2) && tvc->opens > 0 - && !(tvc->states & CUnlinked)) { + && !(tvc->states & CUnlinked)) +#else +#ifdef AFS_DARWIN14_ENV + if (tvc && (VREFCOUNT(tvc) > 1 + DARWIN_REFBASE) && tvc->opens > 0 && !(tvc->states & CUnlinked)) #else if (tvc && (VREFCOUNT(tvc) > 1) && tvc->opens > 0 - && !(tvc->states & CUnlinked)) { + && !(tvc->states & CUnlinked)) +#endif #endif + { char *unlname = newname(); ReleaseWriteLock(&adp->lock); @@ -454,6 +459,7 @@ afs_remunlink(register struct vcache *avc, register int doit) struct VenusFid dirFid; register struct dcache *tdc; afs_int32 code = 0; + int oldref; if (NBObtainWriteLock(&avc->lock, 423)) return 0; @@ -470,7 +476,7 @@ afs_remunlink(register struct vcache *avc, register int doit) cred = avc->uncred; avc->uncred = NULL; -#ifdef AFS_DARWIN_ENV +#if defined(AFS_DARWIN_ENV) && !defined(AFS_DARWIN14_ENV) /* this is called by vrele (via VOP_INACTIVE) when the refcount * is 0. we can't just call VN_HOLD since vref will panic. * we can't just call osi_vnhold because a later AFS_RELE will call @@ -488,6 +494,12 @@ afs_remunlink(register struct vcache *avc, register int doit) */ avc->states &= ~(CUnlinked | CUnlinkedDel); +#ifdef AFS_DARWIN14_ENV + if (VREFCOUNT(avc) < 4) { + oldref = 4 - VREFCOUNT(avc); + VREFCOUNT_SET(avc, 4); + } +#endif ReleaseWriteLock(&avc->lock); dirFid.Cell = avc->fid.Cell; @@ -512,8 +524,15 @@ afs_remunlink(register struct vcache *avc, register int doit) osi_FreeSmallSpace(unlname); crfree(cred); #ifdef AFS_DARWIN_ENV +#ifndef AFS_DARWIN14_ENV osi_Assert(VREFCOUNT(avc) == 1); VREFCOUNT_SET(avc, 0); +#else + if (oldref) { + int newref = VREFCOUNT(avc) - oldref; + VREFCOUNT_SET(avc, newref); + } +#endif #endif } } else { diff --git a/src/afs/afs_vcache.c b/src/afs/afs_vcache.c index a4c113030..188ba6a03 100644 --- a/src/afs/afs_vcache.c +++ b/src/afs/afs_vcache.c @@ -822,8 +822,15 @@ afs_NewVCache(struct VenusFid *afid, struct server *serverp) refpanic("VLRU inconsistent"); } #ifdef AFS_DARWIN_ENV + if ((VREFCOUNT(tvc) < DARWIN_REFBASE) || + (VREFCOUNT(tvc) < 1+DARWIN_REFBASE && + UBCINFOEXISTS(&tvc->v))) { + VREFCOUNT_SET(tvc, + DARWIN_REFBASE + (UBCINFOEXISTS(&tvc->v) ? 1 : 0)); + } if (tvc->opens == 0 && ((tvc->states & CUnlinkedDel) == 0) - && VREFCOUNT(tvc) == 1 && UBCINFOEXISTS(&tvc->v)) { + && VREFCOUNT(tvc) == DARWIN_REFBASE+1 + && UBCINFOEXISTS(&tvc->v)) { osi_VM_TryReclaim(tvc, &fv_slept); if (fv_slept) { uq = VLRU.prev; @@ -843,7 +850,13 @@ afs_NewVCache(struct VenusFid *afid, struct server *serverp) } #endif - if (VREFCOUNT(tvc) == 0 && tvc->opens == 0 + if (VREFCOUNT(tvc) == +#ifdef AFS_DARWIN_ENV + DARWIN_REFBASE +#else + 0 +#endif + && tvc->opens == 0 && (tvc->states & CUnlinkedDel) == 0) { #if defined(AFS_XBSD_ENV) /* @@ -1148,7 +1161,7 @@ afs_NewVCache(struct VenusFid *afid, struct server *serverp) /* VLISTNONE(&tvc->v); */ tvc->v.v_freelist.tqe_next = 0; tvc->v.v_freelist.tqe_prev = (struct vnode **)0xdeadb; - /*tvc->vrefCount++; */ + tvc->vrefCount+=DARWIN_REFBASE; #endif /* * The proper value for mvstat (for root fids) is setup by the caller. @@ -1361,7 +1374,8 @@ afs_FlushActiveVcaches(register afs_int32 doflocks) } } #ifdef AFS_DARWIN_ENV - if (VREFCOUNT(tvc) == 1 && UBCINFOEXISTS(&tvc->v)) { + if (VREFCOUNT(tvc) == 1+DARWIN_REFBASE + && UBCINFOEXISTS(&tvc->v)) { if (tvc->opens) panic("flushactive open, hasubc, but refcnt 1"); osi_VM_TryReclaim(tvc, 0); @@ -2178,6 +2192,22 @@ afs_GetRootVCache(struct VenusFid *afid, struct vrequest *areq, if (vg) continue; #endif /* AFS_OSF_ENV */ +#ifdef AFS_DARWIN14_ENV + /* It'd really suck if we allowed duplicate vcaches for the + same fid to happen. Wonder if this will work? */ + struct vnode *vp = AFSTOV(tvc); + if (vp->v_flag & (VXLOCK|VORECLAIM|VTERMINATE)) { + printf("precluded FindVCache on %x (%d:%d:%d)\n", + vp, tvc->fid.Fid.Volume, tvc->fid.Fid.Vnode, + tvc->fid.Fid.Unique); + simple_lock(&vp->v_interlock); + SET(vp->v_flag, VTERMWANT); + simple_unlock(&vp->v_interlock); + (void)tsleep((caddr_t)&vp->v_ubcinfo, PINOD, "vget1", 0); + printf("VTERMWANT ended on %x\n", vp); + continue; + } +#endif break; } } diff --git a/src/config/param.ppc_darwin_12.h b/src/config/param.ppc_darwin_12.h index becb46773..7d2b162aa 100644 --- a/src/config/param.ppc_darwin_12.h +++ b/src/config/param.ppc_darwin_12.h @@ -14,6 +14,7 @@ #define AFS_DARWIN_ENV #define AFS_NONFSTRANS #define AFS_SYSCALL 230 +#define DARWIN_REFBASE 0 /* File system entry (used if mount.h doesn't define MOUNT_AFS */ #define AFS_MOUNT_AFS "afs" @@ -77,6 +78,7 @@ #define AFS_USR_DARWIN_ENV #define AFS_NONFSTRANS #define AFS_SYSCALL 230 +#define DARWIN_REFBASE 0 /* File system entry (used if mount.h doesn't define MOUNT_AFS */ #define AFS_MOUNT_AFS "afs" diff --git a/src/config/param.ppc_darwin_13.h b/src/config/param.ppc_darwin_13.h index 59b9c0421..2c36b97f3 100644 --- a/src/config/param.ppc_darwin_13.h +++ b/src/config/param.ppc_darwin_13.h @@ -15,6 +15,7 @@ #define AFS_DARWIN13_ENV #define AFS_NONFSTRANS #define AFS_SYSCALL 230 +#define DARWIN_REFBASE 0 /* File system entry (used if mount.h doesn't define MOUNT_AFS */ #define AFS_MOUNT_AFS "afs" @@ -80,6 +81,7 @@ #define AFS_USR_DARWIN13_ENV #define AFS_NONFSTRANS #define AFS_SYSCALL 230 +#define DARWIN_REFBASE 0 /* File system entry (used if mount.h doesn't define MOUNT_AFS */ #define AFS_MOUNT_AFS "afs" diff --git a/src/config/param.ppc_darwin_14.h b/src/config/param.ppc_darwin_14.h index 6652e2f84..cb4644804 100644 --- a/src/config/param.ppc_darwin_14.h +++ b/src/config/param.ppc_darwin_14.h @@ -17,6 +17,7 @@ #define AFS_NONFSTRANS #define AFS_SYSCALL 230 #define AFS_NAMEI_ENV 1 +#define DARWIN_REFBASE 0 /* File system entry (used if mount.h doesn't define MOUNT_AFS */ #define AFS_MOUNT_AFS "afs" @@ -84,6 +85,7 @@ #define AFS_USR_DARWIN14_ENV #define AFS_NONFSTRANS #define AFS_SYSCALL 230 +#define DARWIN_REFBASE 0 /* File system entry (used if mount.h doesn't define MOUNT_AFS */ #define AFS_MOUNT_AFS "afs" diff --git a/src/config/param.ppc_darwin_70.h b/src/config/param.ppc_darwin_70.h index e0cb9c05e..82d695c32 100644 --- a/src/config/param.ppc_darwin_70.h +++ b/src/config/param.ppc_darwin_70.h @@ -20,6 +20,7 @@ #define AFS_NONFSTRANS #define AFS_SYSCALL 230 #define AFS_NAMEI_ENV 1 +#define DARWIN_REFBASE 3 /* File system entry (used if mount.h doesn't define MOUNT_AFS */ #define AFS_MOUNT_AFS "afs" @@ -92,6 +93,7 @@ #define AFS_USR_DARWIN70_ENV #define AFS_NONFSTRANS #define AFS_SYSCALL 230 +#define DARWIN_REFBASE 0 /* File system entry (used if mount.h doesn't define MOUNT_AFS */ #define AFS_MOUNT_AFS "afs" -- 2.39.5