freebsd: CM changes targeting RELENG_8
authorMatt Benjamin <matt@linuxbox.com>
Tue, 5 Jan 2010 02:31:27 +0000 (21:31 -0500)
committerDerrick Brashear <shadow|account-1000005@unknown>
Tue, 12 Jan 2010 18:44:06 +0000 (10:44 -0800)
Force all vnodes onto the fs mount queue when allocated.  This fixes
a long-standing vnode recycling problem.  Don't call vgone() on a vnode
whose refcount is 0.  Always destroy vnodes in VOP_RECLAIM.  This is work
in progress towards fixing old reclaim bug mentioned in Rees comment.
Hold vnode returned from gop_lookupname_user in afs_pioctl_syscall,
to avoid it going inactive before we're finished.  Also unlock it if
necessary.  Don't use custom vop_lock impl when AFS_FBSD80_ENV.  Remove
duplicate conditional code in vnode pretty-print (old cruft).  Also don't
format fid members as hex. Revert vn_lock exclusve in osi_VM_StoreAllSegments
(fixes deadlock introduced by me in a 2009 changeset).  Remove unused
variables in osi_VM_StoreAllSegments.

Change-Id: I9fd146d6f405382a20a75523ec2b75c62ac6d17a
Reviewed-on: http://gerrit.openafs.org/1068
Reviewed-by: Derrick Brashear <shadow@dementia.org>
Tested-by: Derrick Brashear <shadow@dementia.org>

src/afs/FBSD/osi_vm.c
src/afs/FBSD/osi_vnodeops.c
src/afs/afs_pioctl.c
src/afs/afs_vcache.c

index 804b473..6a2f136 100644 (file)
@@ -85,7 +85,9 @@
  * therefore obsolescent.
  *
  * OSF/1 Locking:  VN_LOCK has been called.
- * XXX - should FreeBSD have done this, too?  Certainly looks like it.
+ * We do not lock the vnode here, but instead require that it be exclusive
+ * locked by code calling osi_VM_StoreAllSegments directly, or scheduling it
+ * from the bqueue - Matt
  * Maybe better to just call vnode_pager_setsize()?
  */
 int
@@ -159,13 +161,7 @@ osi_VM_StoreAllSegments(struct vcache *avc)
      */
     do {
        anyio = 0;
-#ifdef AFS_FBSD80_ENV
-       lock_vnode(vp);
-#endif
        if (VOP_GETVOBJECT(vp, &obj) == 0 && (obj->flags & OBJ_MIGHTBEDIRTY)) {
-#ifdef AFS_FBSD80_ENV
-           unlock_vnode(vp);
-#endif
 #ifdef AFS_FBSD50_ENV
            if (!vget(vp, LK_EXCLUSIVE | LK_RETRY, curthread)) {
 #else
@@ -180,10 +176,6 @@ osi_VM_StoreAllSegments(struct vcache *avc)
                    vput(vp);
                }
            }
-#ifdef AFS_FBSD80_ENV
-           else
-               unlock_vnode(vp);
-#endif
     } while (anyio && (--tries > 0));
     AFS_GLOCK();
     ObtainWriteLock(&avc->lock, 94);
@@ -202,8 +194,7 @@ void
 osi_VM_TryToSmush(struct vcache *avc, afs_ucred_t *acred, int sync)
 {
     struct vnode *vp;
-    struct vm_object *obj;
-    int anyio, tries, code;
+    int tries, code;
 
     SPLVAR;
 
@@ -211,7 +202,7 @@ osi_VM_TryToSmush(struct vcache *avc, afs_ucred_t *acred, int sync)
 
     if (vp->v_iflag & VI_DOOMED) {
       USERPRI;
-      return 0;
+      return;
     }
 
     if (vp->v_bufobj.bo_object != NULL) {
index 442215c..4842e96 100644 (file)
@@ -93,7 +93,7 @@ static vop_setattr_t  afs_vop_setattr;
 static vop_strategy_t  afs_vop_strategy;
 static vop_symlink_t   afs_vop_symlink;
 static vop_write_t     afs_vop_write;
-#if defined(AFS_FBSD70_ENV) && !defined(AFS_FBSD90_ENV)
+#if defined(AFS_FBSD70_ENV) && !defined(AFS_FBSD80_ENV)
 static vop_lock1_t      afs_vop_lock;
 static vop_unlock_t     afs_vop_unlock;
 static vop_islocked_t   afs_vop_islocked;
@@ -134,7 +134,7 @@ struct vop_vector afs_vnodeops = {
        .vop_strategy =         afs_vop_strategy,
        .vop_symlink =          afs_vop_symlink,
        .vop_write =            afs_vop_write,
-#if defined(AFS_FBSD70_ENV) && !defined(AFS_FBSD90_ENV)
+#if defined(AFS_FBSD70_ENV) && !defined(AFS_FBSD80_ENV)
        .vop_lock1 =            afs_vop_lock,
        .vop_unlock =           afs_vop_unlock,
        .vop_islocked =         afs_vop_islocked,
@@ -1516,15 +1516,11 @@ afs_vop_reclaim(struct vop_reclaim_args *ap)
      */
     if (code)
        printf("afs_vop_reclaim: afs_FlushVCache failed code %d\n", code);
-#ifdef AFS_FBSD60_ENV
-    else {
-       vnode_destroy_vobject(vp);
-#ifndef AFS_FBSD70_ENV
-       vfs_hash_remove(vp);
-#endif
-       vp->v_data = 0;
-    }
-#endif
+
+    /* basically, it must not fail */
+    vnode_destroy_vobject(vp);
+    vp->v_data = 0;
+
     return 0;
 }
 
@@ -1578,17 +1574,10 @@ afs_vop_print(ap)
     register struct vcache *vc = VTOAFS(ap->a_vp);
     int s = vc->f.states;
 
-#ifdef AFS_FBSD50_ENV
-    printf("tag %s, fid: %d.%x.%x.%x, opens %d, writers %d", vp->v_tag,
+    printf("tag %s, fid: %d.%d.%d.%d, opens %d, writers %d", vp->v_tag,
           (int)vc->f.fid.Cell, (u_int) vc->f.fid.Fid.Volume,
           (u_int) vc->f.fid.Fid.Vnode, (u_int) vc->f.fid.Fid.Unique, vc->opens,
           vc->execsOrWriters);
-#else
-    printf("tag %d, fid: %ld.%x.%x.%x, opens %d, writers %d", vp->v_tag,
-          vc->f.fid.Cell, (u_int) vc->f.fid.Fid.Volume,
-          (u_int) vc->f.fid.Fid.Vnode, (u_int) vc->f.fid.Fid.Unique, vc->opens,
-          vc->execsOrWriters);
-#endif
     printf("\n  states%s%s%s%s%s", (s & CStatd) ? " statd" : "",
           (s & CRO) ? " readonly" : "", (s & CDirty) ? " dirty" : "",
           (s & CMAPPED) ? " mapped" : "",
index ebfc6ac..42aa960 100644 (file)
@@ -836,6 +836,9 @@ afs_syscall_pioctl(char *path, unsigned int com, caddr_t cmarg, int follow)
            vp = (struct vnode *)dp->d_inode;
 #else
        code = gop_lookupname_user(path, AFS_UIOUSER, follow, &vp);
+#if defined(AFS_FBSD80_ENV) /* XXX check on 7x */
+       VN_HOLD(vp);
+#endif /* AFS_FBSD80_ENV */
 #endif /* AFS_LINUX22_ENV */
 #endif /* AFS_AIX41_ENV */
        AFS_GLOCK();
@@ -933,6 +936,10 @@ afs_syscall_pioctl(char *path, unsigned int com, caddr_t cmarg, int follow)
 #ifdef AFS_LINUX22_ENV
        dput(dp);
 #else
+#if defined(AFS_FBSD80_ENV)
+    if (VOP_ISLOCKED(vp))
+       VOP_UNLOCK(vp, 0);
+#endif /* AFS_FBSD80_ENV */
        AFS_RELE(vp);           /* put vnode back */
 #endif
     }
index 3c5b3ed..3eed998 100644 (file)
@@ -742,9 +742,9 @@ afs_AllocVCache(void)
     /* none free, making one is better than a panic */
     afs_stats_cmperf.vcacheXAllocs++;  /* count in case we have a leak */
     tvc = (struct vcache *)afs_osi_Alloc(sizeof(struct vcache));
-#if defined(AFS_DARWIN_ENV) && !defined(UKERNEL)
+#if (defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)) && !defined(UKERNEL)
     tvc->v = NULL; /* important to clean this, or use memset 0 */
-#endif
+#endif /* DARWIN || XBSD && !UKERNEL */
 #ifdef KERNEL_HAVE_PIN
     pin((char *)tvc, sizeof(struct vcache));   /* XXX */
 #endif
@@ -889,7 +889,19 @@ afs_NewVCache(struct VenusFid *afid, struct server *serverp)
                  * XXX assume FreeBSD is the same for now.
                  */
                 AFS_GUNLOCK();
+#if defined(AFS_FBSD80_ENV)
+                /* vgone() is correct, but v_usecount is assumed not
+                 * to be 0, and I suspect that currently our usage ensures that
+                 * in fact it will */
+                if (vrefcnt(AFSTOV(tvc)) < 1) {
+                   vref(AFSTOV(tvc));
+                }
+                vn_lock(AFSTOV(tvc), LK_EXCLUSIVE | LK_RETRY); /* !glocked */
+#endif
                 vgone(AFSTOV(tvc));
+#if defined(AFS_FBSD80_ENV)
+                VOP_UNLOCK(AFSTOV(tvc), 0);
+#endif
                 fv_slept = 0;
                 code = 0;
                 AFS_GLOCK();
@@ -1036,6 +1048,14 @@ afs_NewVCache(struct VenusFid *afid, struct server *serverp)
        if (getnewvnode(VT_AFS, afs_globalVFS, afs_vnodeop_p, &vp))
 #endif
            panic("afs getnewvnode");   /* can't happen */
+#ifdef AFS_FBSD70_ENV
+    /* XXX verified on 80--TODO check on 7x */
+    if (!vp->v_mount) {
+        vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); /* !glocked */
+        insmntque(vp, afs_globalVFS);
+        VOP_UNLOCK(vp, 0);
+    }
+#endif
        AFS_GLOCK();
        ObtainWriteLock(&afs_xvcache,339);
        if (tvc->v != NULL) {
@@ -1156,11 +1176,6 @@ afs_NewVCache(struct VenusFid *afid, struct server *serverp)
     tvc->v.v_next = gnodepnt->gn_vnode;        /*Single vnode per gnode for us! */
     gnodepnt->gn_vnode = &tvc->v;
 #endif
-#ifdef AFS_FBSD70_ENV
-#ifndef AFS_FBSD80_ENV /* yup.  they put it back. */
-    insmntque(AFSTOV(tvc), afs_globalVFS);
-#endif
-#endif
 #if defined(AFS_SGI_ENV)
     VN_SET_DPAGES(&(tvc->v), (struct pfdat *)NULL);
     osi_Assert((tvc->v.v_flag & VINACT) == 0);