git: 94cb19f46114 - stable/13 - null_vput_pair(): release use reference on dvp earlier
Konstantin Belousov
kib at FreeBSD.org
Sat Aug 14 10:22:35 UTC 2021
The branch stable/13 has been updated by kib:
URL: https://cgit.FreeBSD.org/src/commit/?id=94cb19f46114950586fc363b518550c171849291
commit 94cb19f46114950586fc363b518550c171849291
Author: Konstantin Belousov <kib at FreeBSD.org>
AuthorDate: 2021-03-07 21:08:38 +0000
Commit: Konstantin Belousov <kib at FreeBSD.org>
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);
}
More information about the dev-commits-src-all
mailing list