diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -187,11 +187,11 @@ } static uint64_t -open2nameif(int fmode, u_int vn_open_flags) +open2nameif(int fmode, u_int vn_open_flags, uint64_t cn_flags) { uint64_t res; - res = ISOPEN | LOCKLEAF; + res = ISOPEN | LOCKLEAF | cn_flags; if ((fmode & O_RESOLVE_BENEATH) != 0) res |= RBENEATH; if ((fmode & O_EMPTY_PATH) != 0) @@ -202,12 +202,19 @@ res |= OPENWRITE; if ((fmode & O_NAMEDATTR) != 0) res |= OPENNAMED | CREATENAMED; + if ((fmode & O_NOFOLLOW) != 0) + res &= ~FOLLOW; + else + res |= FOLLOW; if ((vn_open_flags & VN_OPEN_NOAUDIT) == 0) res |= AUDITVNODE1; + else + res &= ~AUDITVNODE1; if ((vn_open_flags & VN_OPEN_NOCAPCHECK) != 0) res |= NOCAPCHECK; if ((vn_open_flags & VN_OPEN_WANTIOCTLCAPS) != 0) res |= WANTIOCTLCAPS; + return (res); } @@ -258,7 +265,9 @@ return (EINVAL); else if ((fmode & (O_CREAT | O_DIRECTORY)) == O_CREAT) { ndp->ni_cnd.cn_nameiop = CREATE; - ndp->ni_cnd.cn_flags = open2nameif(fmode, vn_open_flags); + ndp->ni_cnd.cn_flags = open2nameif(fmode, vn_open_flags, + ndp->ni_cnd.cn_flags); + /* * Set NOCACHE to avoid flushing the cache when * rolling in many files at once. @@ -269,6 +278,8 @@ ndp->ni_cnd.cn_flags |= LOCKPARENT | NOCACHE | NC_KEEPPOSENTRY; if ((fmode & O_EXCL) == 0 && (fmode & O_NOFOLLOW) == 0) ndp->ni_cnd.cn_flags |= FOLLOW; + else if ((fmode & O_EXCL) != 0) + ndp->ni_cnd.cn_flags &= ~FOLLOW; if ((vn_open_flags & VN_OPEN_INVFS) == 0) bwillwrite(); if ((error = namei(ndp)) != 0) @@ -348,9 +359,8 @@ } } else { ndp->ni_cnd.cn_nameiop = LOOKUP; - ndp->ni_cnd.cn_flags = open2nameif(fmode, vn_open_flags); - ndp->ni_cnd.cn_flags |= (fmode & O_NOFOLLOW) != 0 ? NOFOLLOW : - FOLLOW; + ndp->ni_cnd.cn_flags = open2nameif(fmode, vn_open_flags, + ndp->ni_cnd.cn_flags); if ((fmode & FWRITE) == 0) ndp->ni_cnd.cn_flags |= LOCKSHARED; if ((error = namei(ndp)) != 0)