In nfs_lock(), recheck vp->v_data after lock before accessing it.

We might race with reclaim, and then this is no longer a nfs vnode, in
which case we do not need to handle deferred vnode_pager_setsize()
either.

Reported by:	rk@ronald.org
PR:	 242184
Sponsored by:	The FreeBSD Foundation
MFC after:	3 days
This commit is contained in:
Konstantin Belousov 2019-11-29 13:55:56 +00:00
parent 0b0c23fee3
commit 9698d99230

View File

@ -312,6 +312,8 @@ nfs_lock(struct vop_lock1_args *ap)
if (error != 0 || vp->v_op != &newnfs_vnodeops)
return (error);
np = VTONFS(vp);
if (np == NULL)
return (0);
NFSLOCKNODE(np);
if ((np->n_flag & NVNSETSZSKIP) == 0 || (lktype != LK_SHARED &&
lktype != LK_EXCLUSIVE && lktype != LK_UPGRADE &&
@ -345,6 +347,9 @@ nfs_lock(struct vop_lock1_args *ap)
error = VOP_LOCK1_APV(&default_vnodeops, ap);
if (error != 0 || vp->v_op != &newnfs_vnodeops)
return (error);
if (vp->v_data == NULL)
goto downgrade;
MPASS(vp->v_data == np);
NFSLOCKNODE(np);
if ((np->n_flag & NVNSETSZSKIP) == 0) {
NFSUNLOCKNODE(np);