The branch stable/13 has been updated by kib:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=94cb19f46114950586fc363b518550c171849291

commit 94cb19f46114950586fc363b518550c171849291
Author:     Konstantin Belousov <[email protected]>
AuthorDate: 2021-03-07 21:08:38 +0000
Commit:     Konstantin Belousov <[email protected]>
CommitDate: 2021-08-14 10:21:59 +0000

    null_vput_pair(): release use reference on dvp earlier
    
    (cherry picked from commit 16dea8341024b8ee8be619c27d4e63bd81bd9b6c)
---
 sys/fs/nullfs/null_vnops.c | 45 +++++++++++++++++++++++++++++++--------------
 1 file changed, 31 insertions(+), 14 deletions(-)

diff --git a/sys/fs/nullfs/null_vnops.c b/sys/fs/nullfs/null_vnops.c
index 6a6df55a0bef..e3a320a22bfa 100644
--- a/sys/fs/nullfs/null_vnops.c
+++ b/sys/fs/nullfs/null_vnops.c
@@ -1084,33 +1084,50 @@ null_vput_pair(struct vop_vput_pair_args *ap)
        vpp = ap->a_vpp;
        vp = NULL;
        lvp = NULL;
-       if (vpp != NULL) {
+       mp = NULL;
+       if (vpp != NULL)
                vp = *vpp;
-               if (vp != NULL) {
+       if (vp != NULL) {
+               lvp = NULLVPTOLOWERVP(vp);
+               vref(lvp);
+               if (!ap->a_unlock_vp) {
                        vhold(vp);
+                       vhold(lvp);
                        mp = vp->v_mount;
-                       lvp = NULLVPTOLOWERVP(vp);
-                       if (ap->a_unlock_vp)
-                               vref(lvp);
+                       vfs_ref(mp);
                }
        }
 
-       res = VOP_VPUT_PAIR(ldvp, &lvp, ap->a_unlock_vp);
+       res = VOP_VPUT_PAIR(ldvp, lvp != NULL ? &lvp : NULL, true);
+       if (vp != NULL && ap->a_unlock_vp)
+               vrele(vp);
+       vrele(dvp);
 
-       /* lvp might have been unlocked and vp reclaimed */
-       if (vp != NULL) {
-               if (!ap->a_unlock_vp && vp->v_vnlock != lvp->v_vnlock) {
+       if (vp == NULL || ap->a_unlock_vp)
+               return (res);
+
+       /* lvp has been unlocked and vp might be reclaimed */
+       VOP_LOCK(vp, LK_EXCLUSIVE | LK_RETRY);
+       if (vp->v_data == NULL && vfs_busy(mp, MBF_NOWAIT) == 0) {
+               vput(vp);
+               vget(lvp, LK_EXCLUSIVE | LK_RETRY);
+               if (VN_IS_DOOMED(lvp)) {
+                       vput(lvp);
+                       vget(vp, LK_EXCLUSIVE | LK_RETRY);
+               } else {
                        error = null_nodeget(mp, lvp, &vp1);
                        if (error == 0) {
-                               vput(vp);
                                *vpp = vp1;
+                       } else {
+                               vget(vp, LK_EXCLUSIVE | LK_RETRY);
                        }
                }
-               if (ap->a_unlock_vp)
-                       vrele(vp);
-               vdrop(vp);
+               vfs_unbusy(mp);
        }
-       vrele(dvp);
+       vdrop(lvp);
+       vdrop(vp);
+       vfs_rel(mp);
+
        return (res);
 }
 
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to