summaryrefslogtreecommitdiff
path: root/usr/src/uts
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/uts')
-rw-r--r--usr/src/uts/common/fs/vnode.c34
-rw-r--r--usr/src/uts/common/io/idm/idm_conn_sm.c6
-rw-r--r--usr/src/uts/common/sys/fcntl.h7
-rw-r--r--usr/src/uts/common/sys/file.h1
4 files changed, 42 insertions, 6 deletions
diff --git a/usr/src/uts/common/fs/vnode.c b/usr/src/uts/common/fs/vnode.c
index e16dbbbc8d..9e0b071999 100644
--- a/usr/src/uts/common/fs/vnode.c
+++ b/usr/src/uts/common/fs/vnode.c
@@ -972,6 +972,7 @@ vn_openat(
int estale_retry = 0;
struct shrlock shr;
struct shr_locowner shr_own;
+ boolean_t create;
mode = 0;
accessflags = 0;
@@ -991,8 +992,31 @@ vn_openat(
if (filemode & FAPPEND)
accessflags |= V_APPEND;
+ /*
+ * We need to handle the case of FCREAT | FDIRECTORY and the case of
+ * FEXCL. If all three are specified, then we always fail because we
+ * cannot create a directory through this interface and FEXCL says we
+ * need to fail the request if we can't create it. If, however, only
+ * FCREAT | FDIRECTORY are specified, then we can treat this as the case
+ * of opening a file that already exists. If it exists, we can do
+ * something and if not, we fail. Effectively FCREAT | FDIRECTORY is
+ * treated as FDIRECTORY.
+ */
+ if ((filemode & (FCREAT | FDIRECTORY | FEXCL)) ==
+ (FCREAT | FDIRECTORY | FEXCL)) {
+ return (EINVAL);
+ }
+
+ if ((filemode & (FCREAT | FDIRECTORY)) == (FCREAT | FDIRECTORY)) {
+ create = B_FALSE;
+ } else if ((filemode & FCREAT) != 0) {
+ create = B_TRUE;
+ } else {
+ create = B_FALSE;
+ }
+
top:
- if (filemode & FCREAT) {
+ if (create) {
enum vcexcl excl;
/*
@@ -1089,11 +1113,13 @@ top:
*/
if (error = VOP_ACCESS(vp, mode, accessflags, CRED(), NULL))
goto out;
+
/*
- * Require FSEARCH to return a directory.
- * Require FEXEC to return a regular file.
+ * Require FSEARCH and FDIRECTORY to return a directory. Require
+ * FEXEC to return a regular file.
*/
- if ((filemode & FSEARCH) && vp->v_type != VDIR) {
+ if ((filemode & (FSEARCH|FDIRECTORY)) != 0 &&
+ vp->v_type != VDIR) {
error = ENOTDIR;
goto out;
}
diff --git a/usr/src/uts/common/io/idm/idm_conn_sm.c b/usr/src/uts/common/io/idm/idm_conn_sm.c
index 011a1ca784..45ba8872b8 100644
--- a/usr/src/uts/common/io/idm/idm_conn_sm.c
+++ b/usr/src/uts/common/io/idm/idm_conn_sm.c
@@ -23,6 +23,7 @@
* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013 by Delphix. All rights reserved.
* Copyright 2017 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2020 Joyent, Inc.
*/
#include <sys/cpuvar.h>
@@ -341,6 +342,7 @@ idm_conn_event_handler(void *event_ctx_opaque)
*/
IDM_SM_LOG(CE_NOTE, "*** drop PDU %p", (void *) pdu);
idm_pdu_complete(pdu, IDM_STATUS_FAIL);
+ event_ctx->iec_info = (uintptr_t)NULL;
break;
default:
ASSERT(0);
@@ -420,6 +422,10 @@ idm_conn_event_handler(void *event_ctx_opaque)
}
}
break;
+ case CA_DROP:
+ /* Already completed above. */
+ ASSERT3P(event_ctx->iec_info, ==, NULL);
+ break;
default:
ASSERT(0);
break;
diff --git a/usr/src/uts/common/sys/fcntl.h b/usr/src/uts/common/sys/fcntl.h
index 3167fd4a1d..cf55ebbf2a 100644
--- a/usr/src/uts/common/sys/fcntl.h
+++ b/usr/src/uts/common/sys/fcntl.h
@@ -86,6 +86,9 @@ extern "C" {
#define O_NOFOLLOW 0x20000 /* don't follow symlinks */
#define O_NOLINKS 0x40000 /* don't allow multiple hard links */
#define O_CLOEXEC 0x800000 /* set the close-on-exec flag */
+#if !defined(_STRICT_SYMBOLS) || defined(_XPG7)
+#define O_DIRECTORY 0x1000000 /* fail if not a directory */
+#endif
/*
* fcntl(2) requests
@@ -181,7 +184,7 @@ extern "C" {
#endif /* _STRICT_SYMBOLS */
#endif /* _LP64 || _FILE_OFFSET_BITS == 32 */
-#if defined(_LARGEFILE64_SOURCE)
+#if defined(_LARGEFILE64_SOURCE)
#if !defined(_LP64) || defined(_KERNEL)
/*
@@ -260,7 +263,7 @@ typedef struct flock32 {
/* transitional large file interface version */
-#if defined(_LARGEFILE64_SOURCE)
+#if defined(_LARGEFILE64_SOURCE)
typedef struct flock64 {
short l_type;
diff --git a/usr/src/uts/common/sys/file.h b/usr/src/uts/common/sys/file.h
index f63f2a10da..816f6a7d33 100644
--- a/usr/src/uts/common/sys/file.h
+++ b/usr/src/uts/common/sys/file.h
@@ -118,6 +118,7 @@ typedef struct fpollinfo {
#define FEXEC 0x400000 /* O_EXEC = 0x400000 */
#define FCLOEXEC 0x800000 /* O_CLOEXEC = 0x800000 */
+#define FDIRECTORY 0x1000000 /* O_DIRECTORY = 0x1000000 */
#if defined(_KERNEL) || defined(_FAKE_KERNEL)