From: Derrick Brashear Date: Mon, 18 Oct 2004 06:45:36 +0000 (+0000) Subject: STABLE12-darwin-updates-20040623 X-Git-Tag: openafs-stable-1_2_12~11 X-Git-Url: https://git.michaelhowe.org/gitweb/?a=commitdiff_plain;h=3863bb58b5caafa12a3025bb7c6fedcb2862ae50;p=packages%2Fo%2Fopenafs.git STABLE12-darwin-updates-20040623 this should be switched to use the freebsd style getnewvnode perhaps it will be --- diff --git a/src/afs/DARWIN/osi_vm.c b/src/afs/DARWIN/osi_vm.c index 8f924183e..78324189e 100644 --- a/src/afs/DARWIN/osi_vm.c +++ b/src/afs/DARWIN/osi_vm.c @@ -43,7 +43,7 @@ osi_VM_FlushVCache(avc, slept) if (UBCINFOEXISTS(vp)) return EBUSY; #endif - if (avc->vrefCount) + if (avc->vrefCount > DARWIN_REFBASE) return EBUSY; if (avc->opens) @@ -179,6 +179,9 @@ void osi_VM_TryReclaim(avc, slept) struct proc *p=current_proc(); struct vnode *vp=AFSTOV(avc); void *obj; +#ifdef AFS_DARWIN14_ENV + int didhold; +#endif if (slept) *slept=0; @@ -187,7 +190,7 @@ void osi_VM_TryReclaim(avc, 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; @@ -198,6 +201,11 @@ void osi_VM_TryReclaim(avc, 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); @@ -212,7 +220,9 @@ void osi_VM_TryReclaim(avc, slept) return; } +#ifndef AFS_DARWIN14_ENV vp->v_usecount--; /* we want the usecount to be 1 */ +#endif if (slept) { ReleaseWriteLock(&afs_xvcache); @@ -229,48 +239,92 @@ void osi_VM_TryReclaim(avc, slept) ubc_release(vp); #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())) { + printf("ubc_release didn't release the reference?!\n"); + } else { +#ifdef AFS_DARWIN14_ENV + 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); + 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); + obj = ubc_getobject(vp); #endif + (void)ubc_clean(vp, 1); #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); - } - } - } 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 - simple_unlock(&vp->v_interlock); - } - AFS_GLOCK(); - if (slept) - ObtainWriteLock(&afs_xvcache,175); - else - ObtainReadLock(&afs_xvcache); + vinvalbuf(vp, V_SAVE, &afs_osi_cred, p, 0, 0); + if (vp->v_usecount == +#ifdef AFS_DARWIN14_ENV + 2 + DARWIN_REFBASE +#else + 1 +#endif + ) + VOP_INACTIVE(vp, p); + else + VOP_UNLOCK(vp, 0, p); +#ifdef AFS_DARWIN14_ENV + if (didhold) + ubc_rele(vp); +#endif + 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); + } + } +#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); + else + ObtainReadLock(&afs_xvcache); } void osi_VM_NukePages(struct vnode *vp, off_t offset, off_t size) { diff --git a/src/afs/DARWIN/osi_vnodeops.c b/src/afs/DARWIN/osi_vnodeops.c index 0a1fb4007..3dd79ea5a 100644 --- a/src/afs/DARWIN/osi_vnodeops.c +++ b/src/afs/DARWIN/osi_vnodeops.c @@ -352,6 +352,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; @@ -445,7 +456,6 @@ afs_vop_pagein(ap) struct iovec aiov; struct uio * uio = &auio; int nocommit = flags & UPL_NOCOMMIT; - int iosize; int code; struct vcache *tvc=VTOAFS(vp); @@ -569,6 +579,7 @@ afs_vop_pageout(ap) struct iovec aiov; struct uio * uio = &auio; int nocommit = flags & UPL_NOCOMMIT; + int iosize; int code; struct vcache *tvc=VTOAFS(vp); @@ -821,7 +832,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 f4668e3ea..b9e634c2d 100644 --- a/src/afs/VNOPS/afs_vnop_remove.c +++ b/src/afs/VNOPS/afs_vnop_remove.c @@ -367,10 +367,18 @@ tagain: Tadp1 = adp; Tadpr = VREFCOUNT(adp); Ttvc = tvc; Tnam = aname; Tnam1 = 0; if (tvc) Ttvcr = VREFCOUNT(tvc); #ifdef AFS_AIX_ENV - if (tvc && (VREFCOUNT(tvc) > 2) && tvc->opens > 0 && !(tvc->states & CUnlinked)) { + if (tvc && (VREFCOUNT(tvc) > 2) && tvc->opens > 0 + && !(tvc->states & CUnlinked)) #else - if (tvc && (VREFCOUNT(tvc) > 1) && tvc->opens > 0 && !(tvc->states & CUnlinked)) { +#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)) +#endif #endif + { + char *unlname = newname(); ReleaseWriteLock(&adp->lock); @@ -417,6 +425,7 @@ afs_remunlink(avc, doit) struct VenusFid dirFid; register struct dcache *tdc; afs_int32 offset, len, code=0; + int oldref; if (NBObtainWriteLock(&avc->lock, 423)) return 0; @@ -434,7 +443,7 @@ afs_remunlink(avc, 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 @@ -452,6 +461,12 @@ afs_remunlink(avc, 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; @@ -475,8 +490,15 @@ afs_remunlink(avc, 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 } } diff --git a/src/afs/afs_vcache.c b/src/afs/afs_vcache.c index 58bdfb4fb..5052d483e 100644 --- a/src/afs/afs_vcache.c +++ b/src/afs/afs_vcache.c @@ -787,8 +787,15 @@ struct vcache *afs_NewVCache(struct VenusFid *afid, struct server *serverp, refpanic("VLRU inconsistent"); #ifdef AFS_DARWIN_ENV - if (tvc->opens == 0 && ((tvc->states & CUnlinkedDel) == 0) && - VREFCOUNT(tvc) == 1 && UBCINFOEXISTS(&tvc->v)) { + 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) == DARWIN_REFBASE+1 + && UBCINFOEXISTS(&tvc->v)) { osi_VM_TryReclaim(tvc, &fv_slept); if (fv_slept) { uq = VLRU.prev; @@ -802,8 +809,14 @@ struct vcache *afs_NewVCache(struct VenusFid *afid, struct server *serverp, afs_TryFlushDcacheChildren(tvc); #endif - if (VREFCOUNT(tvc) == 0 && tvc->opens == 0 - && (tvc->states & CUnlinkedDel) == 0) { + if (VREFCOUNT(tvc) == +#ifdef AFS_DARWIN_ENV + DARWIN_REFBASE +#else + 0 +#endif + && tvc->opens == 0 + && (tvc->states & CUnlinkedDel) == 0) { code = afs_FlushVCache(tvc, &fv_slept); if (code == 0) { anumber--; @@ -975,7 +988,7 @@ struct vcache *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 #ifdef AFS_FBSD_ENV lockinit(&tvc->rwlock, PINOD, "vcache rwlock", 0, 0); @@ -1250,7 +1263,8 @@ afs_FlushActiveVcaches(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); } @@ -2035,6 +2049,22 @@ struct vcache *afs_GetRootVCache(struct VenusFid *afid, 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 de44b567c..50165f792 100644 --- a/src/config/param.ppc_darwin_12.h +++ b/src/config/param.ppc_darwin_12.h @@ -11,6 +11,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" diff --git a/src/config/param.ppc_darwin_12_usr.h b/src/config/param.ppc_darwin_12_usr.h index 2a1c7e777..5bd6f537a 100644 --- a/src/config/param.ppc_darwin_12_usr.h +++ b/src/config/param.ppc_darwin_12_usr.h @@ -11,6 +11,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 b2df4fa5c..07dca4316 100644 --- a/src/config/param.ppc_darwin_13.h +++ b/src/config/param.ppc_darwin_13.h @@ -12,6 +12,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" diff --git a/src/config/param.ppc_darwin_13_usr.h b/src/config/param.ppc_darwin_13_usr.h index 7a70c4858..19f8ed7c0 100644 --- a/src/config/param.ppc_darwin_13_usr.h +++ b/src/config/param.ppc_darwin_13_usr.h @@ -12,6 +12,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 8a6ed1779..bed7b27e2 100644 --- a/src/config/param.ppc_darwin_14.h +++ b/src/config/param.ppc_darwin_14.h @@ -14,6 +14,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" diff --git a/src/config/param.ppc_darwin_14_usr.h b/src/config/param.ppc_darwin_14_usr.h index ca107f523..b473bc10f 100644 --- a/src/config/param.ppc_darwin_14_usr.h +++ b/src/config/param.ppc_darwin_14_usr.h @@ -13,6 +13,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 e13e24e4c..473c1acf7 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" diff --git a/src/config/param.ppc_darwin_70_usr.h b/src/config/param.ppc_darwin_70_usr.h index 1167c80bd..3d18c33d1 100644 --- a/src/config/param.ppc_darwin_70_usr.h +++ b/src/config/param.ppc_darwin_70_usr.h @@ -18,6 +18,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"