diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c --- a/sys/kern/uipc_usrreq.c +++ b/sys/kern/uipc_usrreq.c @@ -594,8 +594,19 @@ error = mac_vnode_check_create(td->td_ucred, nd.ni_dvp, &nd.ni_cnd, &vattr); #endif - if (error == 0) + if (error == 0) { + /* + * The prior lookup may have left LK_SHARED in cn_lkflags, + * and VOP_CREATE technically only requires the new vnode to + * be locked shared. Most filesystems will return the new vnode + * locked exclusive regardless, but we should explicitly + * specify that here since we require it and assert to that + * effect below. + */ + nd.ni_cnd.cn_lkflags = (nd.ni_cnd.cn_lkflags & ~LK_SHARED) | + LK_EXCLUSIVE; error = VOP_CREATE(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr); + } NDFREE_PNBUF(&nd); if (error) { VOP_VPUT_PAIR(nd.ni_dvp, NULL, true);