diff options
Diffstat (limited to 'usr/src/uts')
| -rw-r--r-- | usr/src/uts/common/fs/vnode.c | 34 | ||||
| -rw-r--r-- | usr/src/uts/common/io/idm/idm_conn_sm.c | 6 | ||||
| -rw-r--r-- | usr/src/uts/common/sys/fcntl.h | 7 | ||||
| -rw-r--r-- | usr/src/uts/common/sys/file.h | 1 |
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) |
