darwin-updates-20040623
[openafs.git] / src / afs / DARWIN / osi_vm.c
index 0c2b1a1..7f9cae4 100644 (file)
@@ -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