Print this page
11679 vn_rele() and friends should VERIFY after mutex
Reviewed by: Dan McDonald <danmcd@joyent.com>
        
@@ -20,10 +20,11 @@
  */
 
 /*
  * Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2020 Joyent, Inc.
+ * Copyright 2022 Spencer Evans-Cole.
  * Copyright 2016 Nexenta Systems, Inc.  All rights reserved.
  * Copyright (c) 2011, 2017 by Delphix. All rights reserved.
  * Copyright 2021 OmniOS Community Edition (OmniOSce) Association.
  */
 
@@ -840,35 +841,36 @@
  * on a vnode.
  */
 void
 vn_rele(vnode_t *vp)
 {
-        VERIFY(vp->v_count > 0);
         mutex_enter(&vp->v_lock);
         if (vp->v_count == 1) {
                 mutex_exit(&vp->v_lock);
                 VOP_INACTIVE(vp, CRED(), NULL);
                 return;
+        } else {
+                VERIFY(vp->v_count > 0);
         }
         VN_RELE_LOCKED(vp);
         mutex_exit(&vp->v_lock);
 }
 
 void
 vn_phantom_rele(vnode_t *vp)
 {
-        VERIFY(vp->v_count > 0);
-
         mutex_enter(&vp->v_lock);
         VERIFY3U(vp->v_count, >=, vp->v_phantom_count);
         vp->v_phantom_count--;
         DTRACE_PROBE1(vn__phantom_rele, vnode_t *, vp);
         if (vp->v_count == 1) {
                 ASSERT0(vp->v_phantom_count);
                 mutex_exit(&vp->v_lock);
                 VOP_INACTIVE(vp, CRED(), NULL);
                 return;
+        } else {
+                VERIFY(vp->v_count > 0);
         }
         VN_RELE_LOCKED(vp);
         mutex_exit(&vp->v_lock);
 }
 
@@ -891,12 +893,12 @@
  * only by the DNLC.
  */
 void
 vn_rele_dnlc(vnode_t *vp)
 {
-        VERIFY((vp->v_count > 0) && (vp->v_count_dnlc > 0));
         mutex_enter(&vp->v_lock);
+        VERIFY((vp->v_count > 0) && (vp->v_count_dnlc > 0));
         if (--vp->v_count_dnlc == 0) {
                 if (vp->v_count == 1) {
                         mutex_exit(&vp->v_lock);
                         VOP_INACTIVE(vp, CRED(), NULL);
                         return;
@@ -914,17 +916,18 @@
  * path from accessing a stream head that is going away.
  */
 void
 vn_rele_stream(vnode_t *vp)
 {
-        VERIFY(vp->v_count > 0);
         mutex_enter(&vp->v_lock);
         vp->v_stream = NULL;
         if (vp->v_count == 1) {
                 mutex_exit(&vp->v_lock);
                 VOP_INACTIVE(vp, CRED(), NULL);
                 return;
+        } else {
+                VERIFY(vp->v_count > 0);
         }
         VN_RELE_LOCKED(vp);
         mutex_exit(&vp->v_lock);
 }
 
@@ -945,17 +948,18 @@
  * This is because taskqs throttle back allocation if too many are created.
  */
 void
 vn_rele_async(vnode_t *vp, taskq_t *taskq)
 {
-        VERIFY(vp->v_count > 0);
         mutex_enter(&vp->v_lock);
         if (vp->v_count == 1) {
                 mutex_exit(&vp->v_lock);
                 VERIFY(taskq_dispatch(taskq, (task_func_t *)vn_rele_inactive,
                     vp, TQ_SLEEP) != TASKQID_INVALID);
                 return;
+        } else {
+                VERIFY(vp->v_count > 0);
         }
         VN_RELE_LOCKED(vp);
         mutex_exit(&vp->v_lock);
 }