Author: mjg
Date: Sun Dec  8 21:11:25 2019
New Revision: 355534
URL: https://svnweb.freebsd.org/changeset/base/355534

Log:
  vfs: factor out vnode destruction out of vdrop
  
  Sponsored by: The FreeBSD Foundation

Modified:
  head/sys/kern/vfs_subr.c

Modified: head/sys/kern/vfs_subr.c
==============================================================================
--- head/sys/kern/vfs_subr.c    Sun Dec  8 20:42:58 2019        (r355533)
+++ head/sys/kern/vfs_subr.c    Sun Dec  8 21:11:25 2019        (r355534)
@@ -1663,6 +1663,64 @@ alloc:
        return (0);
 }
 
+static void
+freevnode(struct vnode *vp)
+{
+       struct bufobj *bo;
+
+       /*
+        * The vnode has been marked for destruction, so free it.
+        *
+        * The vnode will be returned to the zone where it will
+        * normally remain until it is needed for another vnode. We
+        * need to cleanup (or verify that the cleanup has already
+        * been done) any residual data left from its current use
+        * so as not to contaminate the freshly allocated vnode.
+        */
+       CTR2(KTR_VFS, "%s: destroying the vnode %p", __func__, vp);
+       atomic_subtract_long(&numvnodes, 1);
+       bo = &vp->v_bufobj;
+       VNASSERT((vp->v_iflag & VI_FREE) == 0, vp,
+           ("cleaned vnode still on the free list."));
+       VNASSERT(vp->v_data == NULL, vp, ("cleaned vnode isn't"));
+       VNASSERT(vp->v_holdcnt == 0, vp, ("Non-zero hold count"));
+       VNASSERT(vp->v_usecount == 0, vp, ("Non-zero use count"));
+       VNASSERT(vp->v_writecount == 0, vp, ("Non-zero write count"));
+       VNASSERT(bo->bo_numoutput == 0, vp, ("Clean vnode has pending I/O's"));
+       VNASSERT(bo->bo_clean.bv_cnt == 0, vp, ("cleanbufcnt not 0"));
+       VNASSERT(pctrie_is_empty(&bo->bo_clean.bv_root), vp,
+           ("clean blk trie not empty"));
+       VNASSERT(bo->bo_dirty.bv_cnt == 0, vp, ("dirtybufcnt not 0"));
+       VNASSERT(pctrie_is_empty(&bo->bo_dirty.bv_root), vp,
+           ("dirty blk trie not empty"));
+       VNASSERT(TAILQ_EMPTY(&vp->v_cache_dst), vp, ("vp has namecache dst"));
+       VNASSERT(LIST_EMPTY(&vp->v_cache_src), vp, ("vp has namecache src"));
+       VNASSERT(vp->v_cache_dd == NULL, vp, ("vp has namecache for .."));
+       VNASSERT(TAILQ_EMPTY(&vp->v_rl.rl_waiters), vp,
+           ("Dangling rangelock waiters"));
+       VI_UNLOCK(vp);
+#ifdef MAC
+       mac_vnode_destroy(vp);
+#endif
+       if (vp->v_pollinfo != NULL) {
+               destroy_vpollinfo(vp->v_pollinfo);
+               vp->v_pollinfo = NULL;
+       }
+#ifdef INVARIANTS
+       /* XXX Elsewhere we detect an already freed vnode via NULL v_op. */
+       vp->v_op = NULL;
+#endif
+       vp->v_mountedhere = NULL;
+       vp->v_unpcb = NULL;
+       vp->v_rdev = NULL;
+       vp->v_fifoinfo = NULL;
+       vp->v_lasta = vp->v_clen = vp->v_cstart = vp->v_lastw = 0;
+       vp->v_iflag = 0;
+       vp->v_vflag = 0;
+       bo->bo_flag = 0;
+       uma_zfree(vnode_zone, vp);
+}
+
 /*
  * Delete from old mount point vnode list, if on one.
  */
@@ -3150,7 +3208,6 @@ vholdnz(struct vnode *vp)
 void
 _vdrop(struct vnode *vp, bool locked)
 {
-       struct bufobj *bo;
        struct mount *mp;
 
        if (locked)
@@ -3220,57 +3277,7 @@ _vdrop(struct vnode *vp, bool locked)
                }
                return;
        }
-       /*
-        * The vnode has been marked for destruction, so free it.
-        *
-        * The vnode will be returned to the zone where it will
-        * normally remain until it is needed for another vnode. We
-        * need to cleanup (or verify that the cleanup has already
-        * been done) any residual data left from its current use
-        * so as not to contaminate the freshly allocated vnode.
-        */
-       CTR2(KTR_VFS, "%s: destroying the vnode %p", __func__, vp);
-       atomic_subtract_long(&numvnodes, 1);
-       bo = &vp->v_bufobj;
-       VNASSERT((vp->v_iflag & VI_FREE) == 0, vp,
-           ("cleaned vnode still on the free list."));
-       VNASSERT(vp->v_data == NULL, vp, ("cleaned vnode isn't"));
-       VNASSERT(vp->v_holdcnt == 0, vp, ("Non-zero hold count"));
-       VNASSERT(vp->v_usecount == 0, vp, ("Non-zero use count"));
-       VNASSERT(vp->v_writecount == 0, vp, ("Non-zero write count"));
-       VNASSERT(bo->bo_numoutput == 0, vp, ("Clean vnode has pending I/O's"));
-       VNASSERT(bo->bo_clean.bv_cnt == 0, vp, ("cleanbufcnt not 0"));
-       VNASSERT(pctrie_is_empty(&bo->bo_clean.bv_root), vp,
-           ("clean blk trie not empty"));
-       VNASSERT(bo->bo_dirty.bv_cnt == 0, vp, ("dirtybufcnt not 0"));
-       VNASSERT(pctrie_is_empty(&bo->bo_dirty.bv_root), vp,
-           ("dirty blk trie not empty"));
-       VNASSERT(TAILQ_EMPTY(&vp->v_cache_dst), vp, ("vp has namecache dst"));
-       VNASSERT(LIST_EMPTY(&vp->v_cache_src), vp, ("vp has namecache src"));
-       VNASSERT(vp->v_cache_dd == NULL, vp, ("vp has namecache for .."));
-       VNASSERT(TAILQ_EMPTY(&vp->v_rl.rl_waiters), vp,
-           ("Dangling rangelock waiters"));
-       VI_UNLOCK(vp);
-#ifdef MAC
-       mac_vnode_destroy(vp);
-#endif
-       if (vp->v_pollinfo != NULL) {
-               destroy_vpollinfo(vp->v_pollinfo);
-               vp->v_pollinfo = NULL;
-       }
-#ifdef INVARIANTS
-       /* XXX Elsewhere we detect an already freed vnode via NULL v_op. */
-       vp->v_op = NULL;
-#endif
-       vp->v_mountedhere = NULL;
-       vp->v_unpcb = NULL;
-       vp->v_rdev = NULL;
-       vp->v_fifoinfo = NULL;
-       vp->v_lasta = vp->v_clen = vp->v_cstart = vp->v_lastw = 0;
-       vp->v_iflag = 0;
-       vp->v_vflag = 0;
-       bo->bo_flag = 0;
-       uma_zfree(vnode_zone, vp);
+       freevnode(vp);
 }
 
 /*
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to