Un null_vptocnp(), cache vp->v_mount and use it for null_nodeget() call.
The vp vnode is unlocked during the execution of the VOP method and can be reclaimed, zeroing vp->v_data. Caching allows to use the correct mount point. Reported and tested by: pho PR: 235549 Sponsored by: The FreeBSD Foundation MFC after: 1 week
This commit is contained in:
parent
c1a7cfd5df
commit
50ac923f6c
@ -870,11 +870,14 @@ null_vptocnp(struct vop_vptocnp_args *ap)
|
||||
struct vnode **dvp = ap->a_vpp;
|
||||
struct vnode *lvp, *ldvp;
|
||||
struct ucred *cred = ap->a_cred;
|
||||
struct mount *mp;
|
||||
int error, locked;
|
||||
|
||||
locked = VOP_ISLOCKED(vp);
|
||||
lvp = NULLVPTOLOWERVP(vp);
|
||||
vhold(lvp);
|
||||
mp = vp->v_mount;
|
||||
vfs_ref(mp);
|
||||
VOP_UNLOCK(vp, 0); /* vp is held by vn_vptocnp_locked that called us */
|
||||
ldvp = lvp;
|
||||
vref(lvp);
|
||||
@ -882,6 +885,7 @@ null_vptocnp(struct vop_vptocnp_args *ap)
|
||||
vdrop(lvp);
|
||||
if (error != 0) {
|
||||
vn_lock(vp, locked | LK_RETRY);
|
||||
vfs_rel(mp);
|
||||
return (ENOENT);
|
||||
}
|
||||
|
||||
@ -893,9 +897,10 @@ null_vptocnp(struct vop_vptocnp_args *ap)
|
||||
if (error != 0) {
|
||||
vrele(ldvp);
|
||||
vn_lock(vp, locked | LK_RETRY);
|
||||
vfs_rel(mp);
|
||||
return (ENOENT);
|
||||
}
|
||||
error = null_nodeget(vp->v_mount, ldvp, dvp);
|
||||
error = null_nodeget(mp, ldvp, dvp);
|
||||
if (error == 0) {
|
||||
#ifdef DIAGNOSTIC
|
||||
NULLVPTOLOWERVP(*dvp);
|
||||
@ -903,6 +908,7 @@ null_vptocnp(struct vop_vptocnp_args *ap)
|
||||
VOP_UNLOCK(*dvp, 0); /* keep reference on *dvp */
|
||||
}
|
||||
vn_lock(vp, locked | LK_RETRY);
|
||||
vfs_rel(mp);
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user