Date: Thu, 25 Feb 2021 20:52:22 GMT From: Konstantin Belousov <kib@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org Subject: git: 0c3cdbf4293a - releng/13.0 - ffs_vput_pair(): try harder to recover from the vnode reclaim Message-ID: <202102252052.11PKqMV5079319@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch releng/13.0 has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=0c3cdbf4293afa1f6faa50e368e47327957ceb85 commit 0c3cdbf4293afa1f6faa50e368e47327957ceb85 Author: Konstantin Belousov <kib@FreeBSD.org> AuthorDate: 2021-01-27 18:10:51 +0000 Commit: Konstantin Belousov <kib@FreeBSD.org> CommitDate: 2021-02-25 20:49:04 +0000 ffs_vput_pair(): try harder to recover from the vnode reclaim Approved by: re (delphij, gjb) (cherry picked from commit 30bfb2fa0fad8e5bbcce369df46dcaa2e08324f3) --- sys/ufs/ffs/ffs_vnops.c | 39 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/sys/ufs/ffs/ffs_vnops.c b/sys/ufs/ffs/ffs_vnops.c index 623b13790ce0..2ac67adad5f2 100644 --- a/sys/ufs/ffs/ffs_vnops.c +++ b/sys/ufs/ffs/ffs_vnops.c @@ -1924,8 +1924,11 @@ ffs_getpages_async(struct vop_getpages_async_args *ap) static int ffs_vput_pair(struct vop_vput_pair_args *ap) { - struct vnode *dvp, *vp, **vpp; - struct inode *dp; + struct mount *mp; + struct vnode *dvp, *vp, *vp1, **vpp; + struct inode *dp, *ip; + ino_t ip_ino; + u_int64_t ip_gen; int error, vp_locked; dvp = ap->a_dvp; @@ -1940,12 +1943,17 @@ ffs_vput_pair(struct vop_vput_pair_args *ap) return (0); } + mp = NULL; if (vp != NULL) { if (ap->a_unlock_vp) { vput(vp); } else { MPASS(vp->v_type != VNON); vp_locked = VOP_ISLOCKED(vp); + ip = VTOI(vp); + ip_ino = ip->i_number; + ip_gen = ip->i_gen; + mp = vp->v_mount; VOP_UNLOCK(vp); } } @@ -1957,6 +1965,7 @@ ffs_vput_pair(struct vop_vput_pair_args *ap) if (vp == NULL || ap->a_unlock_vp) return (0); + MPASS(mp != NULL); /* * It is possible that vp is reclaimed at this point. Only @@ -1970,5 +1979,29 @@ ffs_vput_pair(struct vop_vput_pair_args *ap) * and respond to dead vnodes by returning ESTALE. */ VOP_LOCK(vp, vp_locked | LK_RETRY); - return (0); + if (!VN_IS_DOOMED(vp)) + return (0); + + /* + * Try harder to recover from reclaimed vp if reclaim was not + * because underlying inode was cleared. We saved inode + * number and inode generation, so we can try to reinstantiate + * exactly same version of inode. If this fails, return + * original doomed vnode and let caller to handle + * consequences. + * + * Note that callers must keep write started around + * VOP_VPUT_PAIR() calls, so it is safe to use mp without + * busying it. + */ + VOP_UNLOCK(vp); + error = ffs_inotovp(mp, ip_ino, ip_gen, LK_EXCLUSIVE, &vp1, + FFSV_REPLACE_DOOMED); + if (error != 0) { + VOP_LOCK(vp, vp_locked | LK_RETRY); + } else { + vrele(vp); + *vpp = vp1; + } + return (error); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202102252052.11PKqMV5079319>