The branch main has been updated by markj:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=99cb3dca4773fe4a16c500f9cb55fcd62cd8d7f3

commit 99cb3dca4773fe4a16c500f9cb55fcd62cd8d7f3
Author:     Mark Johnston <[email protected]>
AuthorDate: 2025-11-11 14:47:06 +0000
Commit:     Mark Johnston <[email protected]>
CommitDate: 2025-11-11 14:58:59 +0000

    vnode: Rework vput() to avoid holding the vnode lock after decrementing
    
    It is not safe to modify the vnode structure after releasing one's
    reference.  Modify vput() to avoid this.  Use refcount_release_if_last()
    to opportunistically call vput_final() with the vnode lock held since we
    need the vnode lock in order to deactivate the vnode, and it's silly to
    drop the vnode lock and immediately reacquire it in this common case.
    
    Note that vunref() has a similar flaw.  D52628 aims to fix the problem
    more holistically, but this change fixes observable panics in the
    meantime.
    
    Reported by:    [email protected]
    Reported by:    [email protected]
    Reviewed by:    kib
    MFC after:      3 days
    Differential Revision:  https://reviews.freebsd.org/D52608
---
 sys/kern/vfs_subr.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
index 58975f7ac932..9cf983f6f89d 100644
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -3713,11 +3713,12 @@ vput(struct vnode *vp)
 
        ASSERT_VOP_LOCKED(vp, __func__);
        ASSERT_VI_UNLOCKED(vp, __func__);
-       if (!refcount_release(&vp->v_usecount)) {
-               VOP_UNLOCK(vp);
+       if (refcount_release_if_last(&vp->v_usecount)) {
+               vput_final(vp, VPUT);
                return;
        }
-       vput_final(vp, VPUT);
+       VOP_UNLOCK(vp);
+       vrele(vp);
 }
 
 /*

Reply via email to