macos103-update-20050403
authorDerrick Brashear <shadow@dementia.org>
Mon, 4 Apr 2005 05:17:56 +0000 (05:17 +0000)
committerDerrick Brashear <shadow@dementia.org>
Mon, 4 Apr 2005 05:17:56 +0000 (05:17 +0000)
use system vnodes. one remaining bug, dangling vnodes at shutdown.

13 files changed:
src/afs/DARWIN/osi_machdep.h
src/afs/DARWIN/osi_module.c
src/afs/DARWIN/osi_vfsops.c
src/afs/DARWIN/osi_vm.c
src/afs/DARWIN/osi_vnodeops.c
src/afs/VNOPS/afs_vnop_attrs.c
src/afs/VNOPS/afs_vnop_remove.c
src/afs/afs.h
src/afs/afs_osi.h
src/afs/afs_pioctl.c
src/afs/afs_vcache.c
src/afsd/afs.rc.darwin
src/config/param.ppc_darwin_70.h

index 63e88de..8850718 100644 (file)
@@ -54,9 +54,10 @@ extern struct timeval time;
 
 #define AFS_PROC        struct proc
 
-#define osi_vnhold(avc,r)  do { \
-       if ((avc)->vrefCount) { VN_HOLD(&((avc)->v)); } \
-       else (avc)->vrefCount = 1;  } while(0)
+#define osi_vnhold(avc,r)       VN_HOLD(AFSTOV(avc))
+#define VN_HOLD(vp) darwin_vn_hold(vp)
+#define VN_RELE(vp) vrele(vp);
+
 
 #define gop_rdwr(rw,gp,base,len,offset,segflg,unit,cred,aresid) \
   vn_rdwr((rw),(gp),(base),(len),(offset),(segflg),(unit),(cred),(aresid),current_proc())
index e880764..d4e1136 100644 (file)
@@ -40,7 +40,9 @@ afs_modload(struct kmod_info *ki, void *data)
        return KERN_FAILURE;
     }
     sysent[SYS_setgroups].sy_call = Afs_xsetgroups;
+#if 0
     sysent[SYS_ioctl].sy_call = afs_xioctl;
+#endif
     sysent[AFS_SYSCALL].sy_call = afs3_syscall;
     sysent[AFS_SYSCALL].sy_narg = 5;
     sysent[AFS_SYSCALL].sy_parallel = 0;
@@ -58,7 +60,9 @@ afs_modunload(struct kmod_info * ki, void *data)
     if (vfsconf_del("afs"))
        return KERN_FAILURE;
     /* give up syscall entries for ioctl & setgroups, which we've stolen */
+#if 0
     sysent[SYS_ioctl].sy_call = ioctl;
+#endif
     sysent[SYS_setgroups].sy_call = setgroups;
     /* give up the stolen syscall entry */
     sysent[AFS_SYSCALL].sy_narg = 0;
index 846bf24..64d085e 100644 (file)
@@ -154,6 +154,15 @@ afs_unmount(mp, flags, p)
            mp->mnt_data = (qaddr_t) - 1;
        } else {
            if (flags & MNT_FORCE) {
+                if (afs_globalVp) {
+                    AFS_GUNLOCK();
+                    vrele(AFSTOV(afs_globalVp));
+                    AFS_GLOCK();
+                }
+               afs_globalVp = NULL;
+               AFS_GUNLOCK();
+               vflush(mp, NULLVP, FORCECLOSE/*0*/);
+               AFS_GLOCK();
                afs_globalVFS = 0;
                afs_shutdown();
            } else {
@@ -234,7 +243,7 @@ afs_vget(mp, lfl, vp)
      int lfl;
 {
     int error;
-    printf("vget called. help!\n");
+    //printf("vget called. help!\n");
     if (vp->v_usecount < 0) {
        vprint("bad usecount", vp);
        panic("afs_vget");
index d6e159f..1285bf2 100644 (file)
@@ -38,55 +38,17 @@ int
 osi_VM_FlushVCache(struct vcache *avc, int *slept)
 {
     struct vnode *vp = AFSTOV(avc);
-#ifdef AFS_DARWIN14_ENV
-    if (UBCINFOEXISTS(vp))
-       return EBUSY;
-#endif
-    if (avc->vrefCount > DARWIN_REFBASE)
-       return EBUSY;
-
-    if (avc->opens)
-       return EBUSY;
-
-    /* if a lock is held, give up */
-    if (CheckLock(&avc->lock))
-       return EBUSY;
+    kern_return_t kret;
+    off_t size;
 
     AFS_GUNLOCK();
-    cache_purge(vp);
-#ifndef AFS_DARWIN14_ENV
-    if (UBCINFOEXISTS(vp)) {
-       ubc_clean(vp, 1);
-       ubc_uncache(vp);
-       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);
-       }
+#if 0
+    if (!(UBCINFOMISSING(vp) || UBCINFORECLAIMED(vp))) {
+      size=ubc_getsize(vp);
+      kret=ubc_invalidate(vp,0,size); 
     }
 #endif
-
+    cache_purge(vp);
     AFS_GLOCK();
 
     return 0;
@@ -161,6 +123,7 @@ osi_VM_FlushPages(struct vcache *avc, struct AFS_UCRED *credp)
            printf("VMFlushPages: invalidate failed (error = %d)\n", kret);
        /* XXX what about when not CStatd */
        if (avc->states & CStatd && size != avc->m.Length)
+         if (UBCISVALID(vp))
            ubc_setsize(vp, avc->m.Length);
     }
 }
@@ -175,181 +138,18 @@ void
 osi_VM_Truncate(struct vcache *avc, int alen, struct AFS_UCRED *acred)
 {
     struct vnode *vp = AFSTOV(avc);
-    if (UBCINFOEXISTS(vp)) {
+    if (UBCINFOEXISTS(vp) && UBCISVALID(vp)) {
        ubc_setsize(vp, alen);
     }
 }
 
-/* vnreclaim and vinactive are probably not aggressive enough to keep
-   enough afs vcaches free, so we try to do some of it ourselves */
-/* XXX there's probably not nearly enough locking here */
-void
-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;
-    VN_HOLD(vp);               /* remove from inactive list */
-    if (!simple_lock_try(&vp->v_interlock)) {
-       AFS_RELE(vp);
-       return;
-    }
-    if (!UBCINFOEXISTS(vp) || vp->v_usecount != 2+DARWIN_REFBASE) {
-       simple_unlock(&vp->v_interlock);
-       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);
-       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);
-       AFS_RELE(vp);
-       return;
-    }
-#endif
-    if (slept && ubc_issetflags(vp, UI_WASMAPPED)) {
-       /* We can't possibly release this in time for this NewVCache to get it */
-       simple_unlock(&vp->v_interlock);
-       AFS_RELE(vp);
-       return;
-    }
-
-#ifndef AFS_DARWIN14_ENV
-    vp->v_usecount--;          /* we want the usecount to be 1 */
-#endif
-
-    if (slept) {
-       ReleaseWriteLock(&afs_xvcache);
-       *slept = 1;
-    } else
-       ReleaseReadLock(&afs_xvcache);
-    AFS_GUNLOCK();
-    obj = 0;
-    if (ubc_issetflags(vp, UI_WASMAPPED)) {
-       simple_unlock(&vp->v_interlock);
-#ifdef  AFS_DARWIN14_ENV
-       ubc_release_named(vp);
-#else
-       ubc_release(vp);
-#endif
-       if (ubc_issetflags(vp, UI_HASOBJREF))
-           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);
-           if ((didhold = ubc_hold(vp)))
-               (void)ubc_clean(vp, 0);
-#else
-#ifdef AFS_DARWIN13_ENV
-           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
-               1
-#endif
-               )
-             VOP_UNLOCK(vp, 0, p); /* was 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 terminating");
-               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)
 {
+#if 0
     void *object;
     struct vcache *avc = VTOAFS(vp);
 
-#ifdef AFS_DARWIN14_ENV
     offset = trunc_page(offset);
     size = round_page(size + 1);
     while (size) {
@@ -358,35 +158,6 @@ osi_VM_NukePages(struct vnode *vp, off_t offset, off_t size)
        size -= PAGE_SIZE;
        offset += PAGE_SIZE;
     }
-#else
-    object = NULL;
-#ifdef AFS_DARWIN13_ENV
-    if (UBCINFOEXISTS(vp))
-       object = ubc_getobject(vp, UBC_NOREACTIVATE);
-#else
-    if (UBCINFOEXISTS(vp))
-       object = ubc_getobject(vp);
-#endif
-    if (!object)
-       return;
-
-    offset = trunc_page(offset);
-    size = round_page(size + 1);
-
-#ifdef AFS_DARWIN13_ENV
-    while (size) {
-       memory_object_page_op(object, (vm_offset_t) offset,
-                             UPL_POP_SET | UPL_POP_BUSY | UPL_POP_DUMP, 0,
-                             0);
-       size -= PAGE_SIZE;
-       offset += PAGE_SIZE;
-    }
-#else
-    /* This is all we can do, and it's not enough. sucks to be us */
-    ubc_setsize(vp, offset);
-    size = (offset + size > avc->m.Length) ? offset + size : avc->m.Length;
-    ubc_setsize(vp, size);
-#endif
 #endif
 }
 
@@ -397,34 +168,23 @@ osi_VM_Setup(struct vcache *avc, int force)
     struct vnode *vp = AFSTOV(avc);
 
     if (UBCISVALID(vp) && ((avc->states & CStatd) || force)) {
-       if (!UBCINFOEXISTS(vp) && !ISSET(vp->v_flag, VTERMINATE)) {
+       if (!UBCINFOEXISTS(vp)) {
            osi_vnhold(avc, 0);
            avc->states |= CUBCinit;
            AFS_GUNLOCK();
-           if ((error = ubc_info_init(&avc->v))) {
+           if ((error = ubc_info_init(vp))) {
                AFS_GLOCK();
                avc->states &= ~CUBCinit;
-               AFS_RELE(AFSTOV(avc));
+               AFS_RELE(vp);
                return error;
            }
-#ifndef AFS_DARWIN14_ENV
-           simple_lock(&avc->v.v_interlock);
-           if (!ubc_issetflags(&avc->v, UI_HASOBJREF))
-#ifdef AFS_DARWIN13_ENV
-               if (ubc_getobject
-                   (&avc->v, (UBC_NOREACTIVATE | UBC_HOLDOBJECT)))
-                   panic("VM_Setup: null object");
-#else
-               (void)_ubc_getobject(&avc->v, 1);       /* return value not used */
-#endif
-           simple_unlock(&avc->v.v_interlock);
-#endif
            AFS_GLOCK();
            avc->states &= ~CUBCinit;
-           AFS_RELE(AFSTOV(avc));
+           AFS_RELE(vp);
+       }
+       if (UBCINFOEXISTS(vp) && UBCISVALID(vp)) {
+           ubc_setsize(vp, avc->m.Length);
        }
-       if (UBCINFOEXISTS(&avc->v))
-           ubc_setsize(&avc->v, avc->m.Length);
     }
     return 0;
 }
index 5eda837..cd49634 100644 (file)
@@ -139,7 +139,32 @@ struct vnodeopv_desc afs_vnodeop_opv_desc =
 
 #define DROPNAME() FREE(name, M_TEMP)
 
+void 
+darwin_vn_hold(struct vnode *vp)
+{
+    int haveGlock=ISAFS_GLOCK(); 
+    struct vcache *tvc = VTOAFS(vp);
+
+    tvc->states |= CUBCinit;
+    if (haveGlock) AFS_GUNLOCK(); 
+
+    /* vget needed for 0 ref'd vnode in GetVCache to not panic in vref.
+       vref needed for multiref'd vnode in vnop_remove not to deadlock
+       ourselves during vop_inactive, except we also need to not reinst
+       the ubc... so we just call VREF there now anyway. */
+
+    if (VREFCOUNT(tvc) > 0)
+       VREF(((struct vnode *)(vp))); 
+    else
+       afs_vget(afs_globalVFS, 0, (vp));
 
+    if (UBCINFOMISSING(vp) || UBCINFORECLAIMED(vp)) {
+       ubc_info_init(vp); 
+    }
+
+    if (haveGlock) AFS_GLOCK(); 
+    tvc->states &= ~CUBCinit;
+}
 
 int
 afs_vop_lookup(ap)
@@ -190,14 +215,9 @@ afs_vop_lookup(ap)
 
     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. */
@@ -264,15 +284,9 @@ afs_vop_create(ap)
        (*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)) {
-#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);
+           vcp->states |= CUBCinit;
+           ubc_info_init(*ap->a_vpp);
+           vcp->states &= ~CUBCinit;
        }
     } else
        *ap->a_vpp = 0;
@@ -331,7 +345,9 @@ afs_vop_open(ap)
     if (AFSTOV(vc) != vp)
        panic("AFS open changed vnode!");
 #endif
+#if 0
     osi_FlushPages(vc, ap->a_cred);
+#endif
     AFS_GUNLOCK();
 #ifdef AFS_DARWIN14_ENV
     if (error && didhold)
@@ -357,29 +373,10 @@ afs_vop_close(ap)
        code = afs_close(avc, ap->a_fflag, ap->a_cred, ap->a_p);
     else
        code = afs_close(avc, ap->a_fflag, &afs_osi_cred, ap->a_p);
+#if 0
     osi_FlushPages(avc, ap->a_cred);   /* hold bozon lock, but not basic vnode lock */
-    AFS_GUNLOCK();
-#ifdef AFS_DARWIN14_ENV
-    if (UBCINFOEXISTS(ap->a_vp) && ap->a_vp->v_ubcinfo->ui_refcount < 2) {
-       ubc_hold(ap->a_vp);
-       if (ap->a_vp->v_ubcinfo->ui_refcount < 2) {
-           printf("afs: Imminent ui_refcount panic\n");
-       } else {
-           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
+    AFS_GUNLOCK();
 
     return code;
 }
@@ -410,6 +407,7 @@ afs_vop_getattr(ap)
                                 * } */ *ap;
 {
     int code;
+
     AFS_GLOCK();
     code = afs_getattr(VTOAFS(ap->a_vp), ap->a_vap, ap->a_cred);
     AFS_GUNLOCK();
@@ -442,9 +440,12 @@ afs_vop_read(ap)
                                 * } */ *ap;
 {
     int code;
-    struct vcache *avc = VTOAFS(ap->a_vp);
+    struct vnode *vp = ap->a_vp;
+    struct vcache *avc = VTOAFS(vp);
     AFS_GLOCK();
+#if 0
     osi_FlushPages(avc, ap->a_cred);   /* hold bozon lock, but not basic vnode lock */
+#endif
     code = afs_read(avc, ap->a_uio, ap->a_cred, 0, 0, 0);
     AFS_GUNLOCK();
     return code;
@@ -520,7 +521,9 @@ afs_vop_pagein(ap)
     auio.uio_resid = aiov.iov_len = size;
     aiov.iov_base = (caddr_t) ioaddr;
     AFS_GLOCK();
+#if 0
     osi_FlushPages(tvc, ap->a_cred);   /* hold bozon lock, but not basic vnode lock */
+#endif
     code = afs_read(tvc, uio, cred, 0, 0, 0);
     if (code == 0) {
        ObtainWriteLock(&tvc->lock, 2);
@@ -561,9 +564,12 @@ afs_vop_write(ap)
     struct vcache *avc = VTOAFS(ap->a_vp);
     void *object;
     AFS_GLOCK();
+#if 0
     osi_FlushPages(avc, ap->a_cred);   /* hold bozon lock, but not basic vnode lock */
-    if (UBCINFOEXISTS(ap->a_vp))
+#endif
+    if (UBCINFOEXISTS(ap->a_vp)) {
        ubc_clean(ap->a_vp, 1);
+    }
     if (UBCINFOEXISTS(ap->a_vp))
        osi_VM_NukePages(ap->a_vp, ap->a_uio->uio_offset,
                         ap->a_uio->uio_resid);
@@ -703,7 +709,9 @@ afs_vop_pageout(ap)
 #endif /* ] USV */
 
     AFS_GLOCK();
+#if 0
     osi_FlushPages(tvc, ap->a_cred);   /* hold bozon lock, but not basic vnode lock */
+#endif
     ObtainWriteLock(&tvc->lock, 1);
     afs_FakeOpen(tvc);
     ReleaseWriteLock(&tvc->lock);
@@ -808,14 +816,15 @@ afs_vop_fsync(ap)
     int wait = ap->a_waitfor == MNT_WAIT;
     int error;
     register struct vnode *vp = ap->a_vp;
+    int haveGlock = ISAFS_GLOCK();
 
-    AFS_GLOCK();
-    /*vflushbuf(vp, wait); */
+    /* afs_vop_lookup glocks, can call us through vinvalbuf from GetVCache */
+    if (!haveGlock) AFS_GLOCK();
     if (ap->a_cred)
        error = afs_fsync(VTOAFS(vp), ap->a_cred);
     else
        error = afs_fsync(VTOAFS(vp), &afs_osi_cred);
-    AFS_GUNLOCK();
+    if (!haveGlock) AFS_GUNLOCK();
     return error;
 }
 
@@ -850,25 +859,19 @@ afs_vop_remove(ap)
     error = afs_remove(VTOAFS(dvp), name, cnp->cn_cred);
     AFS_GUNLOCK();
     cache_purge(vp);
-    if (!error && UBCINFOEXISTS(vp)) {
-#ifdef AFS_DARWIN14_ENV
+    vput(dvp);
+    if (!error) {
+        /* necessary so we don't deadlock ourselves in vclean */
+        VOP_UNLOCK(vp, 0, cnp->cn_proc);
+
        /* 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);
-       if (wasmapped)
-           (void)ubc_uncache(vp);
-       if (hasobjref)
-           ubc_release(vp);
-       /* WARNING vp may not be valid after this */
-#endif
+        (void)ubc_uncache(vp);
     }
+
     if (dvp == vp)
        vrele(vp);
     else
        vput(vp);
-    vput(dvp);
 
     FREE_ZONE(cnp->cn_pnbuf, cnp->cn_pnlen, M_NAMEI);
     DROPNAME();
@@ -933,14 +936,14 @@ afs_vop_rename(ap)
     register struct vnode *fdvp = ap->a_fdvp;
     struct proc *p = fcnp->cn_proc;
 
-       /* Check for cross-device rename.
-        * For AFS, this means anything not in AFS-space
-        */
-       if ((0 != strcmp(tdvp->v_mount->mnt_stat.f_fstypename, "afs")) ||
-               (tvp && (0 != strcmp(tvp->v_mount->mnt_stat.f_fstypename, "afs")))) {
-                       error = EXDEV;
-                       goto abortit;
-       }
+    /* Check for cross-device rename.
+     * For AFS, this means anything not in AFS-space
+     */
+    if ((0 != strcmp(tdvp->v_mount->mnt_stat.f_fstypename, "afs")) ||
+       (tvp && (0 != strcmp(tvp->v_mount->mnt_stat.f_fstypename, "afs")))) {
+       error = EXDEV;
+       goto abortit;
+    }
 
     /*
      * if fvp == tvp, we're just removing one name of a pair of
@@ -1217,30 +1220,25 @@ afs_vop_reclaim(ap)
                                 * struct vnode *a_vp;
                                 * } */ *ap;
 {
-    int error;
+    int error = 0;
     int sl;
     register struct vnode *vp = ap->a_vp;
+    int haveGlock = ISAFS_GLOCK();
+    struct vcache *tvc = VTOAFS(vp);
 
     cache_purge(vp);           /* just in case... */
+    if (!haveGlock)
+       AFS_GLOCK();
+    error = afs_FlushVCache(VTOAFS(vp), &sl);  /* toss our stuff from vnode */
+    if (!haveGlock)
+       AFS_GUNLOCK();
 
-#if 0
-    AFS_GLOCK();
-    error = afs_FlushVCache(VTOAFS(vp), &sl);  /* tosses our stuff from vnode */
-    AFS_GUNLOCK();
-    ubc_unlink(vp);
     if (!error && vp->v_data)
        panic("afs_reclaim: vnode not cleaned");
-    return error;
-#else
-    if (vp->v_usecount == 2) {
-       vprint("reclaim count==2", vp);
-    } else if (vp->v_usecount == 1) {
-       vprint("reclaim count==1", vp);
-    } else
-       vprint("reclaim bad count", vp);
+    if (!error && (tvc->v != NULL)) 
+        panic("afs_reclaim: vcache not cleaned");
 
-    return 0;
-#endif
+    return error;
 }
 
 int
@@ -1254,6 +1252,7 @@ afs_vop_lock(ap)
 
     if (vp->v_tag == VT_NON)
        return (ENOENT);
+
     return (lockmgr(&avc->rwlock, ap->a_flags, &vp->v_interlock, ap->a_p));
 }
 
@@ -1265,6 +1264,7 @@ afs_vop_unlock(ap)
 {
     struct vnode *vp = ap->a_vp;
     struct vcache *avc = VTOAFS(vp);
+
     return (lockmgr
            (&avc->rwlock, ap->a_flags | LK_RELEASE, &vp->v_interlock,
             ap->a_p));
@@ -1282,7 +1282,6 @@ afs_vop_bmap(ap)
                                 * int *a_runb;
                                 * } */ *ap;
 {
-    struct vcache *vcp;
     int error;
     if (ap->a_bnp) {
        *ap->a_bnp = ap->a_bn * (PAGE_SIZE / DEV_BSIZE);
@@ -1497,3 +1496,13 @@ afs_vop_cmap(ap)
     *ap->a_run = MAX(ap->a_size, AFS_CHUNKSIZE(ap->a_foffset));
     return 0;
 }
+
+void
+afs_darwin_getnewvnode(struct vcache *tvc)
+{
+    while (getnewvnode(VT_AFS, afs_globalVFS, afs_vnodeop_p, &tvc->v)) {
+        /* no vnodes available, force an alloc (limits be damned)! */
+       printf("failed to get vnode\n");
+    }
+    tvc->v->v_data = (void *)tvc;
+}
index fd15059..84fd3f2 100644 (file)
@@ -94,8 +94,8 @@ afs_CopyOutAttrs(register struct vcache *avc, register struct vattr *attrs)
 #elif defined(AFS_OSF_ENV)
     attrs->va_fsid = avc->v.v_mount->m_stat.f_fsid.val[0];
 #elif defined(AFS_DARWIN70_ENV)
-    attrs->va_fsid = avc->v.v_mount->mnt_stat.f_fsid.val[0];
-#else 
+    attrs->va_fsid = avc->v->v_mount->mnt_stat.f_fsid.val[0];
+#else /* ! AFS_DARWIN70_ENV */
     attrs->va_fsid = 1;
 #endif 
     if (avc->mvstat == 2) {
index 5a1fb9d..301e4e9 100644 (file)
@@ -376,14 +376,9 @@ afs_remove(OSI_VC_ARG(adp), aname, acred)
     if (tvc && (VREFCOUNT(tvc) > 2) && tvc->opens > 0
        && !(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))
 #endif
-#endif
     {
        char *unlname = afs_newname();
 
@@ -429,9 +424,6 @@ afs_remunlink(register struct vcache *avc, register int doit)
     struct VenusFid dirFid;
     register struct dcache *tdc;
     afs_int32 code = 0;
-#ifdef AFS_DARWIN14_ENV
-    int oldref;
-#endif
 
     if (NBObtainWriteLock(&avc->lock, 423))
        return 0;
@@ -448,30 +440,17 @@ afs_remunlink(register struct vcache *avc, register int doit)
            cred = avc->uncred;
            avc->uncred = NULL;
 
-#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
-            * vrele again, which will try to call VOP_INACTIVE again after
-            * vn_locking the vnode. which would be fine except that our vrele
-            * caller also locked the vnode... So instead, we just gimmick the
-            * refcounts and hope nobody else can touch the file now */
-           osi_Assert(VREFCOUNT(avc) == 0);
-           VREFCOUNT_SET(avc, 1);
-#endif
+#ifdef AFS_DARWIN_ENV
+           VREF(AFSTOV(avc));
+#else
            VN_HOLD(AFSTOV(avc));
+#endif
 
            /* We'll only try this once. If it fails, just release the vnode.
             * Clear after doing hold so that NewVCache doesn't find us yet.
             */
            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;
@@ -495,17 +474,6 @@ 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 {
        ReleaseWriteLock(&avc->lock);
index 1ec276d..6c7d4b6 100644 (file)
@@ -551,7 +551,7 @@ struct SimpleLocks {
 #define VPageCleaning 0x2      /* Solaris - Cache Trunc Daemon sez keep out */
 
 #define        CPSIZE      2
-#if defined(AFS_XBSD_ENV)
+#if defined(AFS_XBSD_ENV) || defined(AFS_DARWIN_ENV)
 #define vrefCount   v->v_usecount
 #else
 #define vrefCount   v.v_count
@@ -594,7 +594,7 @@ struct vtodc {
 extern afs_uint32 afs_stampValue;      /* stamp for pair's usage */
 #define        MakeStamp()     (++afs_stampValue)
 
-#if defined(AFS_XBSD_ENV)
+#if defined(AFS_XBSD_ENV) || defined(AFS_DARWIN_ENV)
 #define VTOAFS(v) ((struct vcache *)(v)->v_data)
 #define AFSTOV(vc) ((vc)->v)
 #else
@@ -612,7 +612,7 @@ extern afs_uint32 afs_stampValue;   /* stamp for pair's usage */
  * !(avc->nextfree) && !avc->vlruq.next => (FreeVCList == avc->nextfree)
  */
 struct vcache {
-#if defined(AFS_XBSD_ENV)
+#if defined(AFS_XBSD_ENV)||defined(AFS_DARWIN_ENV)
     struct vnode *v;
 #else
     struct vnode v;            /* Has reference count in v.v_count */
index 7390437..62c14ba 100644 (file)
@@ -119,6 +119,16 @@ struct afs_osi_WaitHandle {
 /*
  * Vnode related macros
  */
+#if defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV)
+#define vSetVfsp(vc, vfsp)      AFSTOV(vc)->v_mount = (vfsp)
+#define vSetType(vc, type)      AFSTOV(vc)->v_type = (type)
+#define vType(vc)               AFSTOV(vc)->v_type
+#else
+#define        vType(vc)           (vc)->v.v_type
+#define        vSetType(vc,type)   (vc)->v.v_type = (type)
+#define        vSetVfsp(vc,vfsp)   (vc)->v.v_vfsp = (vfsp)
+#endif
+
 #ifndef AFS_OBSD_ENV
 #if defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV)
 extern int (**afs_vnodeop_p) ();
@@ -129,9 +139,6 @@ extern struct vnodeops *afs_ops;
 #define        IsAfsVnode(vc)      ((vc)->v_op == afs_ops)
 #define        SetAfsVnode(vc)     (vc)->v_op = afs_ops
 #endif
-#define        vType(vc)           (vc)->v.v_type
-#define        vSetType(vc,type)   (vc)->v.v_type = (type)
-#define        vSetVfsp(vc,vfsp)   (vc)->v.v_vfsp = (vfsp)
 #endif
 
 #ifdef AFS_SGI65_ENV
index 2523b70..a85298b 100644 (file)
@@ -528,16 +528,16 @@ afs_xioctl(void)
     register int ioctlDone = 0, code = 0;
 
     AFS_STATCNT(afs_xioctl);
-#if defined(AFS_XBSD_ENV)
+#if defined(AFS_DARWIN_ENV)
+    if ((code = fdgetf(p, uap->fd, &fd)))
+       return code;
+#elif defined(AFS_XBSD_ENV)
     fdp = p->p_fd;
     if ((u_int) uap->fd >= fdp->fd_nfiles
        || (fd = fdp->fd_ofiles[uap->fd]) == NULL)
        return EBADF;
     if ((fd->f_flag & (FREAD | FWRITE)) == 0)
        return EBADF;
-#elif defined(AFS_DARWIN_ENV)
-    if ((code = fdgetf(p, uap->fd, &fd)))
-       return code;
 #elif defined(AFS_LINUX22_ENV)
     ua.com = com;
     ua.arg = arg;
index 0b72cca..74957b3 100644 (file)
@@ -183,7 +183,7 @@ afs_FlushVCache(struct vcache *avc, int *slept)
        afs_osi_Free(avc->linkData, strlen(avc->linkData) + 1);
        avc->linkData = NULL;
     }
-#if defined(AFS_XBSD_ENV)
+#if defined(AFS_XBSD_ENV) || defined(AFS_DARWIN_ENV)
     /* OK, there are no internal vrefCounts, so there shouldn't
      * be any more refs here. */
     if (avc->v) {
@@ -664,30 +664,14 @@ afs_NewVCache(struct VenusFid *afid, struct server *serverp)
 
            if (tvc->states & CVFlushed) {
                refpanic("CVFlushed on VLRU");
+#if 0
            } else if (i++ > 2 * afs_cacheStats) {      /* even allowing for a few xallocs... */
                refpanic("Increase -stat parameter of afsd(VLRU cycle?)");
+#endif
            } else if (QNext(uq) != tq) {
                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) == DARWIN_REFBASE + 1
-               && UBCINFOEXISTS(&tvc->v)) {
-               osi_VM_TryReclaim(tvc, &fv_slept);
-               if (fv_slept) {
-                   uq = VLRU.prev;
-                   i = 0;
-                   continue;   /* start over - may have raced. */
-               }
-           }
-#elif defined(AFS_LINUX22_ENV)
+#if defined(AFS_LINUX22_ENV)
            if (tvc != afs_globalVp && VREFCOUNT(tvc) && tvc->opens == 0) {
                 struct dentry *dentry;
                 struct list_head *cur, *head = &(AFSTOI(tvc))->i_dentry;
@@ -727,14 +711,13 @@ restart:
            }
 #endif
 
-           if (VREFCOUNT(tvc) ==
-#ifdef AFS_DARWIN_ENV
-               DARWIN_REFBASE
-#else
-               0
+           if (((VREFCOUNT(tvc) == 0) 
+#if defined(AFS_DARWIN_ENV) && !defined(UKERNEL) 
+                || ((VREFCOUNT(tvc) == 1) && 
+                    (UBCINFOEXISTS(AFSTOV(tvc))))
 #endif
-               && tvc->opens == 0 && (tvc->states & CUnlinkedDel) == 0) {
-#if defined(AFS_XBSD_ENV)
+                ) && tvc->opens == 0 && (tvc->states & CUnlinkedDel) == 0) {
+#if defined (AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
                /*
                 * vgone() reclaims the vnode, which calls afs_FlushVCache(),
                 * then it puts the vnode on the free list.
@@ -742,7 +725,9 @@ restart:
                 * not on the free list.
                 * XXX assume FreeBSD is the same for now.
                 */
+               AFS_GUNLOCK();
                vgone(AFSTOV(tvc));
+               AFS_GLOCK();
                code = fv_slept = 0;
 #else
                code = afs_FlushVCache(tvc, &fv_slept);
@@ -763,7 +748,11 @@ restart:
     if (!freeVCList) {
        /* none free, making one is better than a panic */
        afs_stats_cmperf.vcacheXAllocs++;       /* count in case we have a leak */
+       if (afs_cacheStats == afs_stats_cmperf.vcacheXAllocs) printf("would vlru cycle panic\n");
        tvc = (struct vcache *)afs_osi_Alloc(sizeof(struct vcache));
+#if defined(AFS_DARWIN_ENV) && !defined(UKERNEL)
+       tvc->v = NULL; /* important to clean this, or use memset 0 */
+#endif
 #ifdef KERNEL_HAVE_PIN
        pin((char *)tvc, sizeof(struct vcache));        /* XXX */
 #endif
@@ -792,7 +781,7 @@ restart:
     }
 #endif /* AFS_OSF_ENV */
 
-#if defined(AFS_XBSD_ENV)
+#if defined(AFS_XBSD_ENV) || defined(AFS_DARWIN_ENV)
     if (tvc->v)
        panic("afs_NewVCache(): free vcache with vnode attached");
 #endif
@@ -814,6 +803,12 @@ restart:
     AFS_GLOCK();
     lockinit(&tvc->rwlock, PINOD, "vcache", 0, 0);
 #endif
+#ifdef AFS_DARWIN_ENV
+    AFS_GUNLOCK();
+    afs_darwin_getnewvnode(tvc);       /* includes one refcount */
+    AFS_GLOCK();
+    lockinit(&tvc->rwlock, PINOD, "vcache", 0, 0);
+#endif
 #ifdef AFS_FBSD_ENV
     {
        struct vnode *vp;
@@ -949,7 +944,7 @@ restart:
     /* Hold it for the LRU (should make count 2) */
     VN_HOLD(AFSTOV(tvc));
 #else /* AFS_OSF_ENV */
-#if !defined(AFS_XBSD_ENV)
+#if !(defined (AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV))
     VREFCOUNT_SET(tvc, 1);     /* us */
 #endif /* AFS_XBSD_ENV */
 #endif /* AFS_OSF_ENV */
@@ -1021,17 +1016,6 @@ restart:
 #else
     SetAfsVnode(AFSTOV(tvc));
 #endif /* AFS_SGI64_ENV */
-#ifdef AFS_DARWIN_ENV
-    tvc->v.v_ubcinfo = UBC_INFO_NULL;
-    lockinit(&tvc->rwlock, PINOD, "vcache rwlock", 0, 0);
-    cache_purge(AFSTOV(tvc));
-    tvc->v.v_data = tvc;
-    tvc->v.v_tag = VT_AFS;
-    /* VLISTNONE(&tvc->v); */
-    tvc->v.v_freelist.tqe_next = 0;
-    tvc->v.v_freelist.tqe_prev = (struct vnode **)0xdeadb;
-    tvc->vrefCount += DARWIN_REFBASE;
-#endif
     /*
      * The proper value for mvstat (for root fids) is setup by the caller.
      */
@@ -1236,14 +1220,6 @@ afs_FlushActiveVcaches(register afs_int32 doflocks)
                    crfree(cred);
                }
            }
-#ifdef AFS_DARWIN_ENV
-           if (VREFCOUNT(tvc) == 1 + DARWIN_REFBASE
-               && UBCINFOEXISTS(&tvc->v)) {
-               if (tvc->opens)
-                   panic("flushactive open, hasubc, but refcnt 1");
-               osi_VM_TryReclaim(tvc, 0);
-           }
-#endif
        }
     }
     ReleaseReadLock(&afs_xvcache);
@@ -1585,9 +1561,6 @@ afs_ProcessFS(register struct vcache *avc,
 #ifdef AFS_LINUX22_ENV
     vcache2inode(avc);         /* Set the inode attr cache */
 #endif
-#ifdef AFS_DARWIN_ENV
-    osi_VM_Setup(avc, 1);
-#endif
 
 }                              /*afs_ProcessFS */
 
@@ -1722,9 +1695,6 @@ afs_GetVCache(register struct VenusFid *afid, struct vrequest *areq,
        vcache2inode(tvc);
 #endif
        ReleaseWriteLock(&tvc->lock);
-#ifdef AFS_DARWIN_ENV
-       osi_VM_Setup(tvc, 0);
-#endif
        return tvc;
     }
 #if defined(AFS_OSF_ENV)
@@ -1738,7 +1708,7 @@ afs_GetVCache(register struct VenusFid *afid, struct vrequest *areq,
     uvm_vnp_uncache(AFSTOV(tvc));
     VOP_UNLOCK(AFSTOV(tvc), 0, curproc);
 #endif
-#ifdef AFS_FBSD_ENV
+#if defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV)
     /*
      * XXX - I really don't like this.  Should try to understand better.
      * It seems that sometimes, when we get called, we already hold the
@@ -1763,6 +1733,21 @@ afs_GetVCache(register struct VenusFid *afid, struct vrequest *areq,
        if (!iheldthelock)
            VOP_UNLOCK(vp, LK_EXCLUSIVE, curthread);
 #else
+#ifdef AFS_DARWIN_ENV
+       iheldthelock = VOP_ISLOCKED(vp);
+       if (!iheldthelock)
+           vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, current_proc());
+       /* this is messy. we can call fsync which will try to reobtain this */
+       if (VTOAFS(vp) == tvc) 
+         ReleaseWriteLock(&tvc->lock);
+       if (UBCINFOEXISTS(vp)) {
+         vinvalbuf(vp, V_SAVE, &afs_osi_cred, current_proc(), PINOD, 0);
+       }
+       if (VTOAFS(vp) == tvc) 
+         ObtainWriteLock(&tvc->lock, 954);
+       if (!iheldthelock)
+           VOP_UNLOCK(vp, LK_EXCLUSIVE, current_proc());
+#else
        iheldthelock = VOP_ISLOCKED(vp, curproc);
        if (!iheldthelock)
            vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, curproc);
@@ -1770,6 +1755,7 @@ afs_GetVCache(register struct VenusFid *afid, struct vrequest *areq,
        if (!iheldthelock)
            VOP_UNLOCK(vp, LK_EXCLUSIVE, curproc);
 #endif
+#endif
     }
 #endif
 
@@ -2057,22 +2043,6 @@ 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;
        }
     }
@@ -2529,6 +2499,16 @@ afs_FindVCache(struct VenusFid *afid, afs_int32 * retry, afs_int32 flag)
        if (retry && *retry)
            return 0;
 #endif
+#ifdef AFS_DARWIN_ENV
+       tvc->states |= CUBCinit;
+       AFS_GUNLOCK();
+       if (UBCINFOMISSING(AFSTOV(tvc)) ||
+           UBCINFORECLAIMED(AFSTOV(tvc))) {
+         ubc_info_init(AFSTOV(tvc));
+       }
+       AFS_GLOCK();
+       tvc->states &= ~CUBCinit;
+#endif
        /*
         * only move to front of vlru if we have proper vcache locking)
         */
@@ -2573,10 +2553,6 @@ afs_FindVCache(struct VenusFid *afid, afs_int32 * retry, afs_int32 flag)
     if (tvc && (tvc->states & CStatd))
        vcache2inode(tvc);      /* mainly to reset i_nlink */
 #endif
-#ifdef AFS_DARWIN_ENV
-    if (tvc)
-       osi_VM_Setup(tvc, 0);
-#endif
     return tvc;
 }                              /*afs_FindVCache */
 
index dc7e677..65a9189 100644 (file)
@@ -167,4 +167,4 @@ RestartService()
     StartService
 }
 
-RunService "$1"
+RunService "${1:-start}"
index d3a1e6c..7a2d62d 100644 (file)
@@ -66,8 +66,8 @@
 #define direct          dirent
 #define vnode_t         struct vnode
 
-#define VN_RELE(vp)     vrele(((struct vnode *)(vp)))
-#define VN_HOLD(vp)     VREF(((struct vnode *)(vp)))
+//#define VN_RELE(vp)     vrele(((struct vnode *)(vp)))
+//#define VN_HOLD(vp)     VREF(((struct vnode *)(vp)))
 #define BIND_8_COMPAT
 
 #endif