ufs: add vgone calls for unconstructed vnodes in the error path

This mostly eliminates the requirement that vput never unlocks the vnode
before calling VOP_INACTIVE. Note it may still be present for other
filesystems.

See r356126 for an example bug.

Note vput stopped doing early unlock in r357070 thus this change does
not affect correctness as it is.

Reviewed by:	kib
Differential Revision:	https://reviews.freebsd.org/D23215
This commit is contained in:
Mateusz Guzik 2020-01-26 00:38:06 +00:00
parent dc9a1cb60b
commit 6c44a3e019
2 changed files with 10 additions and 1 deletions

View File

@ -1787,6 +1787,7 @@ ffs_vgetf(mp, ino, flags, vpp, ffs_flags)
* still zero, it will be unlinked and returned to the free
* list by vput().
*/
vgone(vp);
vput(vp);
*vpp = NULL;
return (error);
@ -1797,6 +1798,7 @@ ffs_vgetf(mp, ino, flags, vpp, ffs_flags)
ip->i_din2 = uma_zalloc(uma_ufs2, M_WAITOK);
if ((error = ffs_load_inode(bp, ip, fs, ino)) != 0) {
bqrelse(bp);
vgone(vp);
vput(vp);
*vpp = NULL;
return (error);
@ -1814,6 +1816,7 @@ ffs_vgetf(mp, ino, flags, vpp, ffs_flags)
error = ufs_vinit(mp, I_IS_UFS1(ip) ? &ffs_fifoops1 : &ffs_fifoops2,
&vp);
if (error) {
vgone(vp);
vput(vp);
*vpp = NULL;
return (error);
@ -1849,6 +1852,7 @@ ffs_vgetf(mp, ino, flags, vpp, ffs_flags)
error = mac_vnode_associate_extattr(mp, vp);
if (error) {
/* ufs_inactive will release ip->i_devvp ref. */
vgone(vp);
vput(vp);
*vpp = NULL;
return (error);

View File

@ -1839,6 +1839,7 @@ ufs_mkdir(ap)
if (DOINGSOFTDEP(tvp))
softdep_revert_link(dp, ip);
UFS_VFREE(tvp, ip->i_number, dmode);
vgone(tvp);
vput(tvp);
return (error);
}
@ -1853,6 +1854,7 @@ ufs_mkdir(ap)
if (DOINGSOFTDEP(tvp))
softdep_revert_link(dp, ip);
UFS_VFREE(tvp, ip->i_number, dmode);
vgone(tvp);
vput(tvp);
return (error);
}
@ -1980,7 +1982,7 @@ bad:
UFS_INODE_SET_FLAG(ip, IN_CHANGE);
if (DOINGSOFTDEP(tvp))
softdep_revert_mkdir(dp, ip);
vgone(tvp);
vput(tvp);
}
out:
@ -2607,6 +2609,7 @@ ufs_makeinode(mode, dvp, vpp, cnp, callfunc)
if (DOINGSOFTDEP(tvp))
softdep_revert_link(pdir, ip);
UFS_VFREE(tvp, ip->i_number, mode);
vgone(tvp);
vput(tvp);
return (error);
}
@ -2621,6 +2624,7 @@ ufs_makeinode(mode, dvp, vpp, cnp, callfunc)
if (DOINGSOFTDEP(tvp))
softdep_revert_link(pdir, ip);
UFS_VFREE(tvp, ip->i_number, mode);
vgone(tvp);
vput(tvp);
return (error);
}
@ -2691,6 +2695,7 @@ bad:
UFS_INODE_SET_FLAG(ip, IN_CHANGE);
if (DOINGSOFTDEP(tvp))
softdep_revert_create(VTOI(dvp), ip);
vgone(tvp);
vput(tvp);
return (error);
}