darwin-updates-20040613
authorDerrick Brashear <shadow@dementia.org>
Mon, 14 Jun 2004 09:36:09 +0000 (09:36 +0000)
committerDerrick Brashear <shadow@dementia.org>
Mon, 14 Jun 2004 09:36:09 +0000 (09:36 +0000)
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.

src/afs/DARWIN/osi_vm.c
src/afs/DARWIN/osi_vnodeops.c

index df1f8e5..0c2b1a1 100644 (file)
@@ -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);
index ca2cf2c..9798e03 100644 (file)
@@ -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;