FBSD: band-aid vnode locking in lookup
[openafs.git] / src / afs / FBSD / osi_vnodeops.c
index 4842e96..5215642 100644 (file)
@@ -54,9 +54,6 @@
 #include <sys/malloc.h>
 #include <sys/namei.h>
 #include <sys/unistd.h>
-#ifndef AFS_FBSD50_ENV
-#include <vm/vm_zone.h>
-#endif
 #include <vm/vm_page.h>
 #include <vm/vm_object.h>
 #include <vm/vm_pager.h>
@@ -158,9 +155,6 @@ int afs_vop_putpages(struct vop_putpages_args *);
 int afs_vop_ioctl(struct vop_ioctl_args *);
 static int afs_vop_pathconf(struct vop_pathconf_args *);
 int afs_vop_poll(struct vop_poll_args *);
-#ifndef AFS_FBSD50_ENV
-int afs_vop_mmap(struct vop_mmap_args *);
-#endif
 int afs_vop_fsync(struct vop_fsync_args *);
 int afs_vop_remove(struct vop_remove_args *);
 int afs_vop_link(struct vop_link_args *);
@@ -186,9 +180,6 @@ struct vnodeopv_entry_desc afs_vnodeop_entries[] = {
     {&vop_access_desc, (vop_t *) afs_vop_access},      /* access */
     {&vop_advlock_desc, (vop_t *) afs_vop_advlock},    /* advlock */
     {&vop_bmap_desc, (vop_t *) afs_vop_bmap},  /* bmap */
-#ifndef AFS_FBSD50_ENV
-    {&vop_bwrite_desc, (vop_t *) vop_stdbwrite},
-#endif
     {&vop_close_desc, (vop_t *) afs_vop_close},        /* close */
     {&vop_createvobject_desc, (vop_t *) vop_stdcreatevobject},
     {&vop_destroyvobject_desc, (vop_t *) vop_stddestroyvobject},
@@ -204,9 +195,6 @@ struct vnodeopv_entry_desc afs_vnodeop_entries[] = {
     {&vop_lookup_desc, (vop_t *) afs_vop_lookup},      /* lookup */
     {&vop_mkdir_desc, (vop_t *) afs_vop_mkdir},        /* mkdir */
     {&vop_mknod_desc, (vop_t *) afs_vop_mknod},        /* mknod */
-#ifndef AFS_FBSD50_ENV
-    {&vop_mmap_desc, (vop_t *) afs_vop_mmap},  /* mmap */
-#endif
     {&vop_open_desc, (vop_t *) afs_vop_open},  /* open */
     {&vop_pathconf_desc, (vop_t *) afs_vop_pathconf},  /* pathconf */
     {&vop_poll_desc, (vop_t *) afs_vop_poll},  /* select */
@@ -244,9 +232,20 @@ struct vnodeopv_desc afs_vnodeop_opv_desc =
 
 #define DROPNAME() FREE(name, M_TEMP)
 
-/* This is a bit of a cheat... */
-#ifdef AFS_FBSD50_ENV
-#define a_p a_td
+/*
+ * Here we define compatibility functions/macros for interfaces that
+ * have changed between different FreeBSD versions.
+ */
+#if defined(AFS_FBSD90_ENV)
+static __inline void ma_vm_page_lock_queues(void) {};
+static __inline void ma_vm_page_unlock_queues(void) {};
+static __inline void ma_vm_page_lock(vm_page_t m) { vm_page_lock(m); };
+static __inline void ma_vm_page_unlock(vm_page_t m) { vm_page_unlock(m); };
+#else
+static __inline void ma_vm_page_lock_queues(void) { vm_page_lock_queues(); };
+static __inline void ma_vm_page_unlock_queues(void) { vm_page_unlock_queues(); };
+static __inline void ma_vm_page_lock(vm_page_t m) {};
+static __inline void ma_vm_page_unlock(vm_page_t m) {};
 #endif
 
 #if defined(AFS_FBSD80_ENV)
@@ -259,6 +258,14 @@ struct vnodeopv_desc afs_vnodeop_opv_desc =
 #define MA_VOP_UNLOCK(vp, flags, p) (VOP_UNLOCK(vp, flags, p))
 #endif
 
+#if defined(AFS_FBSD70_ENV)
+#define MA_PCPU_INC(c) PCPU_INC(c)
+#define        MA_PCPU_ADD(c, n) PCPU_ADD(c, n)
+#else
+#define MA_PCPU_INC(c) PCPU_LAZY_INC(c)
+#define        MA_PCPU_ADD(c, n) (c) += (n)
+#endif
+
 #ifdef AFS_FBSD70_ENV
 #ifndef AFS_FBSD80_ENV
 /* From kern_lock.c */
@@ -471,14 +478,10 @@ afs_vop_lookup(ap)
     int error;
     struct vcache *vcp;
     struct vnode *vp, *dvp;
-    register int flags = ap->a_cnp->cn_flags;
+    int flags = ap->a_cnp->cn_flags;
     int lockparent;            /* 1 => lockparent flag is set */
     int wantparent;            /* 1 => wantparent or lockparent flag */
-#ifdef AFS_FBSD50_ENV
     struct thread *p = ap->a_cnp->cn_thread;
-#else
-    struct proc *p = ap->a_cnp->cn_proc;
-#endif
 
     dvp = ap->a_dvp;
     if (dvp->v_type != VDIR) {
@@ -528,7 +531,9 @@ afs_vop_lookup(ap)
      * we also always return the vnode locked. */
 
     if (flags & ISDOTDOT) {
+       MA_VOP_UNLOCK(dvp, 0, p);
        ma_vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
+       ma_vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY, p);
        /* always return the child locked */
        if (lockparent && (flags & ISLASTCN)
            && (error = ma_vn_lock(dvp, LK_EXCLUSIVE, p))) {
@@ -545,7 +550,7 @@ afs_vop_lookup(ap)
            MA_VOP_UNLOCK(dvp, 0, p);   /* done with parent. */
 #endif
        }
-       ma_vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
+       ma_vn_lock(vp, LK_EXCLUSIVE | LK_CANRECURSE | LK_RETRY, p);
        /* always return the child locked */
     }
     *ap->a_vpp = vp;
@@ -569,12 +574,8 @@ afs_vop_create(ap)
 {
     int error = 0;
     struct vcache *vcp;
-    register struct vnode *dvp = ap->a_dvp;
-#ifdef AFS_FBSD50_ENV
+    struct vnode *dvp = ap->a_dvp;
     struct thread *p = ap->a_cnp->cn_thread;
-#else
-    struct proc *p = ap->a_cnp->cn_proc;
-#endif
     GETNAME();
 
     AFS_GLOCK();
@@ -637,7 +638,8 @@ afs_vop_open(ap)
                                 * struct vnode *a_vp;
                                 * int  a_mode;
                                 * struct ucred *a_cred;
-                                * struct proc *a_p;
+                                * struct thread *a_td;
+                                * struct file *a_fp;
                                 * } */ *ap;
 {
     int error;
@@ -663,11 +665,27 @@ afs_vop_close(ap)
                                 * struct vnode *a_vp;
                                 * int  a_fflag;
                                 * struct ucred *a_cred;
-                                * struct proc *a_p;
+                                * struct thread *a_td;
                                 * } */ *ap;
 {
-    int code;
-    struct vcache *avc = VTOAFS(ap->a_vp);
+    int code, iflag;
+    struct vnode *vp = ap->a_vp;
+    struct vcache *avc = VTOAFS(vp);
+
+#if defined(AFS_FBSD80_ENV)
+    VI_LOCK(vp);
+    iflag = vp->v_iflag & VI_DOOMED;
+    VI_UNLOCK(vp);
+    if (iflag & VI_DOOMED) {
+        /* osi_FlushVCache (correctly) calls vgone() on recycled vnodes, we don't
+         * have an afs_close to process, in that case */
+        if (avc->opens != 0)
+            panic("afs_vop_close: doomed vnode %p has vcache %p with non-zero opens %d\n",
+                  vp, avc, avc->opens);
+        return 0;
+    }
+#endif
+
     AFS_GLOCK();
     if (ap->a_cred)
        code = afs_close(avc, ap->a_fflag, ap->a_cred);
@@ -682,9 +700,9 @@ int
 afs_vop_access(ap)
      struct vop_access_args    /* {
                                 * struct vnode *a_vp;
-                                * int  a_mode;
+                                * accmode_t a_accmode;
                                 * struct ucred *a_cred;
-                                * struct proc *a_p;
+                                * struct thread *a_td;
                                 * } */ *ap;
 {
     int code;
@@ -704,13 +722,14 @@ afs_vop_getattr(ap)
                                 * struct vnode *a_vp;
                                 * struct vattr *a_vap;
                                 * struct ucred *a_cred;
-                                * struct proc *a_p;
                                 * } */ *ap;
 {
     int code;
+
     AFS_GLOCK();
     code = afs_getattr(VTOAFS(ap->a_vp), ap->a_vap, ap->a_cred);
     AFS_GUNLOCK();
+
     return code;
 }
 
@@ -720,7 +739,6 @@ afs_vop_setattr(ap)
                                 * struct vnode *a_vp;
                                 * struct vattr *a_vap;
                                 * struct ucred *a_cred;
-                                * struct proc *a_p;
                                 * } */ *ap;
 {
     int code;
@@ -770,9 +788,6 @@ afs_vop_getpages(struct vop_getpages_args *ap)
     struct vnode *vp;
     struct vcache *avc;
 
-#ifdef AFS_FBSD50_ENV
-    GIANT_REQUIRED;
-#endif
     vp = ap->a_vp;
     avc = VTOAFS(vp);
     if ((object = vp->v_object) == NULL) {
@@ -789,36 +804,31 @@ afs_vop_getpages(struct vop_getpages_args *ap)
     {
        vm_page_t m = ap->a_m[ap->a_reqpage];
 
-#ifdef AFS_FBSD50_ENV
        VM_OBJECT_LOCK(object);
-       vm_page_lock_queues();
-#endif
+       ma_vm_page_lock_queues();
        if (m->valid != 0) {
            /* handled by vm_fault now        */
            /* vm_page_zero_invalid(m, TRUE); */
            for (i = 0; i < npages; ++i) {
-               if (i != ap->a_reqpage)
+               if (i != ap->a_reqpage) {
+                   ma_vm_page_lock(ap->a_m[i]);
                    vm_page_free(ap->a_m[i]);
+                   ma_vm_page_unlock(ap->a_m[i]);
+               }
            }
-#ifdef AFS_FBSD50_ENV
-           vm_page_unlock_queues();
+           ma_vm_page_unlock_queues();
            VM_OBJECT_UNLOCK(object);
-#endif
            return (0);
        }
-#ifdef AFS_FBSD50_ENV
-       vm_page_unlock_queues();
+       ma_vm_page_unlock_queues();
        VM_OBJECT_UNLOCK(object);
-#endif
     }
     bp = getpbuf(&afs_pbuf_freecnt);
 
     kva = (vm_offset_t) bp->b_data;
     pmap_qenter(kva, ap->a_m, npages);
-#ifdef AFS_FBSD50_ENV
-    cnt.v_vnodein++;
-    cnt.v_vnodepgsin += npages;
-#endif
+    MA_PCPU_INC(cnt.v_vnodein);
+    MA_PCPU_ADD(cnt.v_vnodepgsin, npages);
 
     iov.iov_base = (caddr_t) kva;
     iov.iov_len = ap->a_count;
@@ -828,11 +838,7 @@ afs_vop_getpages(struct vop_getpages_args *ap)
     uio.uio_resid = ap->a_count;
     uio.uio_segflg = UIO_SYSSPACE;
     uio.uio_rw = UIO_READ;
-#ifdef AFS_FBSD50_ENV
     uio.uio_td = curthread;
-#else
-    uio.uio_procp = curproc;
-#endif
 
     AFS_GLOCK();
     osi_FlushPages(avc, osi_curcred());        /* hold bozon lock, but not basic vnode lock */
@@ -843,31 +849,26 @@ afs_vop_getpages(struct vop_getpages_args *ap)
     relpbuf(bp, &afs_pbuf_freecnt);
 
     if (code && (uio.uio_resid == ap->a_count)) {
-#ifdef AFS_FBSD50_ENV
        VM_OBJECT_LOCK(object);
-       vm_page_lock_queues();
-#endif
+       ma_vm_page_lock_queues();
        for (i = 0; i < npages; ++i) {
            if (i != ap->a_reqpage)
                vm_page_free(ap->a_m[i]);
        }
-#ifdef AFS_FBSD50_ENV
-       vm_page_unlock_queues();
+       ma_vm_page_unlock_queues();
        VM_OBJECT_UNLOCK(object);
-#endif
        return VM_PAGER_ERROR;
     }
 
     size = ap->a_count - uio.uio_resid;
-#ifdef AFS_FBSD50_ENV
     VM_OBJECT_LOCK(object);
-    vm_page_lock_queues();
-#endif
+    ma_vm_page_lock_queues();
     for (i = 0, toff = 0; i < npages; i++, toff = nextoff) {
        vm_page_t m;
        nextoff = toff + PAGE_SIZE;
        m = ap->a_m[i];
 
+       /* XXX not in nfsclient? */
        m->flags &= ~PG_ZERO;
 
        if (nextoff <= size) {
@@ -875,15 +876,22 @@ afs_vop_getpages(struct vop_getpages_args *ap)
             * Read operation filled an entire page
             */
            m->valid = VM_PAGE_BITS_ALL;
+#ifndef AFS_FBSD80_ENV
            vm_page_undirty(m);
+#else
+           KASSERT(m->dirty == 0, ("afs_getpages: page %p is dirty", m));
+#endif
        } else if (size > toff) {
            /*
             * Read operation filled a partial page.
             */
            m->valid = 0;
-           vm_page_set_validclean(m, 0, size - toff);
-           /* handled by vm_fault now        */
-           /* vm_page_zero_invalid(m, TRUE); */
+           vm_page_set_valid(m, 0, size - toff);
+#ifndef AFS_FBSD80_ENV
+           vm_page_undirty(m);
+#else
+           KASSERT(m->dirty == 0, ("afs_getpages: page %p is dirty", m));
+#endif
        }
 
        if (i != ap->a_reqpage) {
@@ -901,23 +909,29 @@ afs_vop_getpages(struct vop_getpages_args *ap)
             */
            if (!code) {
 #if defined(AFS_FBSD70_ENV)
-               if (m->oflags & VPO_WANTED)
+               if (m->oflags & VPO_WANTED) {
 #else
-               if (m->flags & PG_WANTED)
+               if (m->flags & PG_WANTED) {
 #endif
+                   ma_vm_page_lock(m);
                    vm_page_activate(m);
-               else
+                   ma_vm_page_unlock(m);
+               }
+               else {
+                   ma_vm_page_lock(m);
                    vm_page_deactivate(m);
+                   ma_vm_page_unlock(m);
+               }
                vm_page_wakeup(m);
            } else {
+               ma_vm_page_lock(m);
                vm_page_free(m);
+               ma_vm_page_unlock(m);
            }
        }
     }
-#ifdef AFS_FBSD50_ENV
-    vm_page_unlock_queues();
+    ma_vm_page_unlock_queues();
     VM_OBJECT_UNLOCK(object);
-#endif
     return 0;
 }
 
@@ -966,10 +980,6 @@ afs_vop_putpages(struct vop_putpages_args *ap)
     struct vnode *vp;
     struct vcache *avc;
 
-#ifdef AFS_FBSD50_ENV
-    GIANT_REQUIRED;
-#endif
-
     vp = ap->a_vp;
     avc = VTOAFS(vp);
     /* Perhaps these two checks should just be KASSERTs instead... */
@@ -988,10 +998,8 @@ afs_vop_putpages(struct vop_putpages_args *ap)
 
     kva = (vm_offset_t) bp->b_data;
     pmap_qenter(kva, ap->a_m, npages);
-#ifdef AFS_FBSD50_ENV
-    cnt.v_vnodeout++;
-    cnt.v_vnodepgsout += ap->a_count;
-#endif
+    MA_PCPU_INC(cnt.v_vnodeout);
+    MA_PCPU_ADD(cnt.v_vnodepgsout, ap->a_count);
 
     iov.iov_base = (caddr_t) kva;
     iov.iov_len = ap->a_count;
@@ -1001,11 +1009,7 @@ afs_vop_putpages(struct vop_putpages_args *ap)
     uio.uio_resid = ap->a_count;
     uio.uio_segflg = UIO_SYSSPACE;
     uio.uio_rw = UIO_WRITE;
-#ifdef AFS_FBSD50_ENV
     uio.uio_td = curthread;
-#else
-    uio.uio_procp = curproc;
-#endif
     sync = IO_VMIO;
     if (ap->a_sync & VM_PAGER_PUT_SYNC)
        sync |= IO_SYNC;
@@ -1033,11 +1037,11 @@ int
 afs_vop_ioctl(ap)
      struct vop_ioctl_args     /* {
                                 * struct vnode *a_vp;
-                                * int  a_command;
-                                * caddr_t  a_data;
+                                * u_long a_command;
+                                * void *a_data;
                                 * int  a_fflag;
                                 * struct ucred *a_cred;
-                                * struct proc *a_p;
+                                * struct thread *a_td;
                                 * } */ *ap;
 {
     struct vcache *tvc = VTOAFS(ap->a_vp);
@@ -1065,7 +1069,7 @@ afs_vop_poll(ap)
                                 * struct vnode *a_vp;
                                 * int  a_events;
                                 * struct ucred *a_cred;
-                                * struct proc *a_p;
+                                * struct thread *td;
                                 * } */ *ap;
 {
     /*
@@ -1086,7 +1090,7 @@ afs_vop_mmap(ap)
                                 * struct vnode *a_vp;
                                 * int  a_fflags;
                                 * struct ucred *a_cred;
-                                * struct proc *a_p;
+                                * struct thread *td;
                                 * } */ *ap;
 {
     return (EINVAL);
@@ -1096,13 +1100,12 @@ int
 afs_vop_fsync(ap)
      struct vop_fsync_args     /* {
                                 * struct vnode *a_vp;
-                                * struct ucred *a_cred;
                                 * int a_waitfor;
-                                * struct proc *a_p;
+                                * struct thread *td;
                                 * } */ *ap;
 {
     int error;
-    register struct vnode *vp = ap->a_vp;
+    struct vnode *vp = ap->a_vp;
 
     AFS_GLOCK();
     /*vflushbuf(vp, wait); */
@@ -1127,8 +1130,8 @@ afs_vop_remove(ap)
                                 * } */ *ap;
 {
     int error = 0;
-    register struct vnode *vp = ap->a_vp;
-    register struct vnode *dvp = ap->a_dvp;
+    struct vnode *vp = ap->a_vp;
+    struct vnode *dvp = ap->a_dvp;
 
     GETNAME();
     AFS_GLOCK();
@@ -1148,13 +1151,9 @@ afs_vop_link(ap)
                                 * } */ *ap;
 {
     int error = 0;
-    register struct vnode *dvp = ap->a_tdvp;
-    register struct vnode *vp = ap->a_vp;
-#ifdef AFS_FBSD50_ENV
+    struct vnode *dvp = ap->a_tdvp;
+    struct vnode *vp = ap->a_vp;
     struct thread *p = ap->a_cnp->cn_thread;
-#else
-    struct proc *p = ap->a_cnp->cn_proc;
-#endif
 
     GETNAME();
     if (dvp->v_mount != vp->v_mount) {
@@ -1165,7 +1164,7 @@ afs_vop_link(ap)
        error = EISDIR;
        goto out;
     }
-    if ((error = ma_vn_lock(vp, LK_EXCLUSIVE, p)) != 0) {
+    if ((error = ma_vn_lock(vp, LK_CANRECURSE | LK_EXCLUSIVE, p)) != 0) {
        goto out;
     }
     AFS_GLOCK();
@@ -1195,14 +1194,10 @@ afs_vop_rename(ap)
     struct componentname *tcnp = ap->a_tcnp;
     char *tname;
     struct vnode *tvp = ap->a_tvp;
-    register struct vnode *tdvp = ap->a_tdvp;
+    struct vnode *tdvp = ap->a_tdvp;
     struct vnode *fvp = ap->a_fvp;
-    register struct vnode *fdvp = ap->a_fdvp;
-#ifdef AFS_FBSD50_ENV
+    struct vnode *fdvp = ap->a_fdvp;
     struct thread *p = fcnp->cn_thread;
-#else
-    struct proc *p = fcnp->cn_proc;
-#endif
 
     /*
      * Check for cross-device rename.
@@ -1300,15 +1295,11 @@ afs_vop_mkdir(ap)
                                 * struct vattr *a_vap;
                                 * } */ *ap;
 {
-    register struct vnode *dvp = ap->a_dvp;
-    register struct vattr *vap = ap->a_vap;
+    struct vnode *dvp = ap->a_dvp;
+    struct vattr *vap = ap->a_vap;
     int error = 0;
     struct vcache *vcp;
-#ifdef AFS_FBSD50_ENV
     struct thread *p = ap->a_cnp->cn_thread;
-#else
-    struct proc *p = ap->a_cnp->cn_proc;
-#endif
 
     GETNAME();
 #ifdef DIAGNOSTIC
@@ -1340,7 +1331,7 @@ afs_vop_rmdir(ap)
                                 * } */ *ap;
 {
     int error = 0;
-    register struct vnode *dvp = ap->a_dvp;
+    struct vnode *dvp = ap->a_dvp;
 
     GETNAME();
     AFS_GLOCK();
@@ -1378,11 +1369,7 @@ afs_vop_symlink(struct vop_symlink_args *ap)
        error = afs_lookup(VTOAFS(dvp), name, &vcp, cnp->cn_cred);
        if (error == 0) {
            newvp = AFSTOV(vcp);
-#ifdef AFS_FBSD50_ENV
            ma_vn_lock(newvp, LK_EXCLUSIVE | LK_RETRY, cnp->cn_thread);
-#else
-           ma_vn_lock(newvp, LK_EXCLUSIVE | LK_RETRY, cnp->cn_proc);
-#endif
        }
     }
     AFS_GUNLOCK();
@@ -1463,10 +1450,10 @@ int
 afs_vop_inactive(ap)
      struct vop_inactive_args  /* {
                                 * struct vnode *a_vp;
-                                * struct proc *a_p;
+                                * struct thread *td;
                                 * } */ *ap;
 {
-    register struct vnode *vp = ap->a_vp;
+    struct vnode *vp = ap->a_vp;
 
     if (prtactive && vp->v_usecount != 0)
        vprint("afs_vop_inactive(): pushing active", vp);
@@ -1474,8 +1461,8 @@ afs_vop_inactive(ap)
     AFS_GLOCK();
     afs_InactiveVCache(VTOAFS(vp), 0); /* decrs ref counts */
     AFS_GUNLOCK();
-#ifndef AFS_FBSD80_ENV
-    MA_VOP_UNLOCK(vp, 0, ap->a_p);
+#ifndef AFS_FBSD60_ENV
+    MA_VOP_UNLOCK(vp, 0, ap->a_td);
 #endif
     return 0;
 }
@@ -1499,23 +1486,17 @@ afs_vop_reclaim(struct vop_reclaim_args *ap)
        AFS_GLOCK();
     if (!haveVlock)
        ObtainWriteLock(&afs_xvcache, 901);
-#ifndef AFS_DISCON_ENV
-    code = afs_FlushVCache(avc, &slept);       /* tosses our stuff from vnode */
-#else
     /* reclaim the vnode and the in-memory vcache, but keep the on-disk vcache */
-    code = afs_FlushVS(avc);
-#endif
+    code = afs_FlushVCache(avc, &slept);
     if (!haveVlock)
        ReleaseWriteLock(&afs_xvcache);
     if (!haveGlock)
        AFS_GUNLOCK();
 
-    /*
-     * XXX Pretend it worked, to prevent panic on shutdown
-     * Garrett, please fix - Jim Rees
-     */
-    if (code)
-       printf("afs_vop_reclaim: afs_FlushVCache failed code %d\n", code);
+    if (code) {
+       afs_warn("afs_vop_reclaim: afs_FlushVCache failed code %d vnode\n", code);
+       VOP_PRINT(vp);
+    }
 
     /* basically, it must not fail */
     vnode_destroy_vobject(vp);
@@ -1570,11 +1551,11 @@ afs_vop_print(ap)
                                 * struct vnode *a_vp;
                                 * } */ *ap;
 {
-    register struct vnode *vp = ap->a_vp;
-    register struct vcache *vc = VTOAFS(ap->a_vp);
+    struct vnode *vp = ap->a_vp;
+    struct vcache *vc = VTOAFS(ap->a_vp);
     int s = vc->f.states;
 
-    printf("tag %s, fid: %d.%d.%d.%d, opens %d, writers %d", vp->v_tag,
+    printf("vc %p vp %p tag %s, fid: %d.%d.%d.%d, opens %d, writers %d", vc, vp, 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);