diff options
Diffstat (limited to 'sys/kern/vfs_default.c')
-rw-r--r-- | sys/kern/vfs_default.c | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/sys/kern/vfs_default.c b/sys/kern/vfs_default.c index 382fbb2d9ace..3c428d7b7511 100644 --- a/sys/kern/vfs_default.c +++ b/sys/kern/vfs_default.c @@ -423,10 +423,25 @@ int vop_stdadvlock(struct vop_advlock_args *ap) { struct vnode *vp; + struct mount *mp; struct vattr vattr; int error; vp = ap->a_vp; + + /* + * Provide atomicity of open(O_CREAT | O_EXCL | O_EXLOCK) for + * local filesystems. See vn_open_cred() for reciprocal part. + */ + mp = vp->v_mount; + if (mp != NULL && (mp->mnt_flag & MNT_LOCAL) != 0 && + ap->a_op == F_SETLK && (ap->a_flags & F_FIRSTOPEN) == 0) { + VI_LOCK(vp); + while ((vp->v_iflag & VI_FOPENING) != 0) + msleep(vp, VI_MTX(vp), PLOCK, "lockfo", 0); + VI_UNLOCK(vp); + } + if (ap->a_fl->l_whence == SEEK_END) { /* * The NFSv4 server must avoid doing a vn_lock() here, since it |