summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr/src/cmd/truss/codes.c6
-rw-r--r--usr/src/compat/bhyve/sys/fcntl.h2
-rw-r--r--usr/src/man/man2/open.221
-rw-r--r--usr/src/pkg/manifests/system-test-ostest.mf3
-rw-r--r--usr/src/test/os-tests/runfiles/default.run3
-rw-r--r--usr/src/test/os-tests/tests/Makefile1
-rw-r--r--usr/src/test/os-tests/tests/syscall/Makefile55
-rw-r--r--usr/src/test/os-tests/tests/syscall/open.c102
-rw-r--r--usr/src/uts/common/fs/vnode.c17
-rw-r--r--usr/src/uts/common/sys/fcntl.h5
-rw-r--r--usr/src/uts/common/sys/file.h3
11 files changed, 209 insertions, 9 deletions
diff --git a/usr/src/cmd/truss/codes.c b/usr/src/cmd/truss/codes.c
index 88c67ea994..107b36ee87 100644
--- a/usr/src/cmd/truss/codes.c
+++ b/usr/src/cmd/truss/codes.c
@@ -23,7 +23,7 @@
* Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2017 by Delphix. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
- * Copyright 2019 Joyent, Inc.
+ * Copyright 2020 Joyent, Inc.
* Copyright (c) 2014, OmniTI Computer Consulting, Inc. All rights reserved.
*/
@@ -1962,7 +1962,7 @@ pathconfname(int code)
#define ALL_O_FLAGS \
(O_NDELAY|O_APPEND|O_SYNC|O_DSYNC|O_NONBLOCK|O_CREAT|O_TRUNC\
|O_EXCL|O_NOCTTY|O_LARGEFILE|O_RSYNC|O_XATTR|O_NOFOLLOW|O_NOLINKS\
- |O_CLOEXEC|O_DIRECTORY|FXATTRDIROPEN)
+ |O_CLOEXEC|O_DIRECTORY|O_DIRECT|FXATTRDIROPEN)
const char *
openarg(private_t *pri, int arg)
@@ -2024,6 +2024,8 @@ openarg(private_t *pri, int arg)
(void) strlcat(str, "|O_CLOEXEC", sizeof (pri->code_buf));
if (arg & O_DIRECTORY)
(void) strlcat(str, "|O_DIRECTORY", sizeof (pri->code_buf));
+ if (arg & O_DIRECT)
+ (void) strlcat(str, "|O_DIRECT", sizeof (pri->code_buf));
if (arg & FXATTRDIROPEN)
(void) strlcat(str, "|FXATTRDIROPEN", sizeof (pri->code_buf));
diff --git a/usr/src/compat/bhyve/sys/fcntl.h b/usr/src/compat/bhyve/sys/fcntl.h
index 062a3b84ac..9173446e8e 100644
--- a/usr/src/compat/bhyve/sys/fcntl.h
+++ b/usr/src/compat/bhyve/sys/fcntl.h
@@ -16,8 +16,6 @@
#ifndef _COMPAT_FREEBSD_SYS_FCNTL_H_
#define _COMPAT_FREEBSD_SYS_FCNTL_H_
-#define O_DIRECT 0x0
-
#include_next <sys/fcntl.h>
#endif /* _COMPAT_FREEBSD_SYS_FCNTL_H_ */
diff --git a/usr/src/man/man2/open.2 b/usr/src/man/man2/open.2
index 86e00e575a..0e13f5af79 100644
--- a/usr/src/man/man2/open.2
+++ b/usr/src/man/man2/open.2
@@ -46,8 +46,9 @@
.\" Portions Copyright (c) 2013, OmniTI Computer Consulting, Inc.
.\" All Rights Reserved.
.\" Copyright 2015 Nexenta Systems, Inc. All rights reserved.
+.\" Copyright 2020 Joyent, Inc.
.\"
-.TH OPEN 2 "Jan 20, 2020"
+.TH OPEN 2 "Mar 10, 2020"
.SH NAME
open, openat \- open a file
.SH SYNOPSIS
@@ -176,6 +177,19 @@ whether the file is open for reading, writing or for both.
.sp
.ne 2
.na
+.B O_DIRECT
+.ad
+.sp .6
+.RS 4n
+Indicates that the file data is not going to be reused in the near future.
+When possible, data is read or written directly between the application's
+memory and the device when the data is accessed with \fBread\fR(2) and
+\fBwrite\fR(2) operations. See \fBdirectio\fR(3C) for more details.
+.RE
+
+.sp
+.ne 2
+.na
.B O_DIRECTORY
.ad
.sp .6
@@ -619,7 +633,7 @@ The \fIpath\fR argument points to an illegal address.
\fB\fBEINVAL\fR\fR
.ad
.RS 16n
-The system does not support synchronized I/O for this file, or the
+The system does not support synchronized or direct I/O for this file, or the
\fBO_XATTR\fR flag was supplied and the underlying file system does not support
extended file attributes.
.RE
@@ -1018,7 +1032,8 @@ Standard For \fBopen()\fR, see \fBstandards\fR(5).
\fBIntro\fR(2), \fBchmod\fR(2), \fBclose\fR(2), \fBcreat\fR(2), \fBdup\fR(2),
\fBexec\fR(2), \fBfcntl\fR(2), \fBgetmsg\fR(2), \fBgetrlimit\fR(2),
\fBlseek\fR(2), \fBputmsg\fR(2), \fBread\fR(2), \fBstat\fR(2), \fBumask\fR(2),
-\fBwrite\fR(2), \fBattropen\fR(3C), \fBfcntl.h\fR(3HEAD), \fBstat.h\fR(3HEAD),
+\fBwrite\fR(2), \fBattropen\fR(3C), \fBdirectio\fR(3C),
+\fBfcntl.h\fR(3HEAD), \fBstat.h\fR(3HEAD),
\fBunlockpt\fR(3C), \fBattributes\fR(5), \fBlf64\fR(5), \fBprivileges\fR(5),
\fBstandards\fR(5), \fBconnld\fR(7M), \fBstreamio\fR(7I)
.SH NOTES
diff --git a/usr/src/pkg/manifests/system-test-ostest.mf b/usr/src/pkg/manifests/system-test-ostest.mf
index 44dd39c58f..d132b36bf4 100644
--- a/usr/src/pkg/manifests/system-test-ostest.mf
+++ b/usr/src/pkg/manifests/system-test-ostest.mf
@@ -40,6 +40,7 @@ dir path=opt/os-tests/tests/secflags
dir path=opt/os-tests/tests/sigqueue
dir path=opt/os-tests/tests/sockfs
dir path=opt/os-tests/tests/stress
+dir path=opt/os-tests/tests/syscall
dir path=opt/os-tests/tests/timer
dir path=opt/os-tests/tests/uccid
file path=kernel/drv/$(ARCH64)/ksensor_test group=sys
@@ -112,6 +113,8 @@ file path=opt/os-tests/tests/sockfs/rights.64 mode=0555
file path=opt/os-tests/tests/sockfs/sockpair mode=0555
file path=opt/os-tests/tests/spoof-ras mode=0555
file path=opt/os-tests/tests/stress/dladm-kstat mode=0555
+file path=opt/os-tests/tests/syscall/open.32 mode=0555
+file path=opt/os-tests/tests/syscall/open.64 mode=0555
file path=opt/os-tests/tests/timer/timer_limit mode=0555
file path=opt/os-tests/tests/uccid/atrparse mode=0555
file path=opt/os-tests/tests/uccid/excl-badread mode=0555
diff --git a/usr/src/test/os-tests/runfiles/default.run b/usr/src/test/os-tests/runfiles/default.run
index 72158c8bc2..f2f66ab4d7 100644
--- a/usr/src/test/os-tests/runfiles/default.run
+++ b/usr/src/test/os-tests/runfiles/default.run
@@ -76,6 +76,9 @@ user = root
tests = ['conn', 'dgram', 'drop_priv', 'nosignal', 'rights.32', 'rights.64',
'sockpair']
+[/opt/os-tests/tests/syscall]
+tests = ['open.32', 'open.64']
+
[/opt/os-tests/tests/pf_key]
user = root
timeout = 180
diff --git a/usr/src/test/os-tests/tests/Makefile b/usr/src/test/os-tests/tests/Makefile
index 7396e135c9..190c61e134 100644
--- a/usr/src/test/os-tests/tests/Makefile
+++ b/usr/src/test/os-tests/tests/Makefile
@@ -29,6 +29,7 @@ SUBDIRS = \
sockfs \
spoof-ras \
stress \
+ syscall \
timer \
tmpfs \
uccid \
diff --git a/usr/src/test/os-tests/tests/syscall/Makefile b/usr/src/test/os-tests/tests/syscall/Makefile
new file mode 100644
index 0000000000..b4ba83a18b
--- /dev/null
+++ b/usr/src/test/os-tests/tests/syscall/Makefile
@@ -0,0 +1,55 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2020 Joyent, Inc.
+#
+
+include $(SRC)/cmd/Makefile.cmd
+include $(SRC)/test/Makefile.com
+
+PROGS = open
+
+CSTD = $(CSTD_GNU99)
+
+ROOTOPTPKG = $(ROOT)/opt/os-tests
+TESTDIR = $(ROOTOPTPKG)/tests/syscall
+
+PROGS32 = $(PROGS:%=%.32)
+PROGS64 = $(PROGS:%=%.64)
+CMDS = $(PROGS32) $(PROGS64)
+$(CMDS) := FILEMODE = 0555
+
+TESTDIRPROGS = $(PROGS32:%=$(TESTDIR)/%) \
+ $(PROGS64:%=$(TESTDIR)/%)
+
+all: $(PROGS32) $(PROGS64)
+
+install: all $(TESTDIR) $(TESTDIRPROGS)
+
+clobber: clean
+
+clean:
+ -$(RM) $(CMDS)
+
+$(TESTDIR):
+ $(INS.dir)
+
+$(TESTDIR)/%: %
+ $(INS.file)
+
+%.64: %.c
+ $(LINK64.c) -o $@ $< $(LDLIBS64)
+ $(POST_PROCESS)
+
+%.32: %.c
+ $(LINK.c) -o $@ $< $(LDLIBS)
+ $(POST_PROCESS)
diff --git a/usr/src/test/os-tests/tests/syscall/open.c b/usr/src/test/os-tests/tests/syscall/open.c
new file mode 100644
index 0000000000..e7f826b2a5
--- /dev/null
+++ b/usr/src/test/os-tests/tests/syscall/open.c
@@ -0,0 +1,102 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2020 Joyent, Inc.
+ */
+
+/*
+ * Test the open(2) syscall.
+ *
+ * Currently only tests O_DIRECT pass/fail based on the known support in the
+ * underlying file system.
+ *
+ * Note: there is a test for the O_DIRECTORY flag in the directory above this
+ * which could be consolidated into this code at some point.
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/statvfs.h>
+#include <sys/param.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+
+static void
+o_direct_test(const char *dir)
+{
+ int fd;
+ struct statvfs64 buf;
+ char tmpname[MAXPATHLEN];
+ char *path;
+
+ boolean_t pass;
+
+ (void) snprintf(tmpname, sizeof (tmpname), "%s/otstXXXXXX", dir);
+ if ((path = mktemp(tmpname)) == NULL) {
+ (void) printf("FAILED: unable to create temp file name\n");
+ exit(1);
+ }
+
+ if (statvfs64(dir, &buf) == -1) {
+ perror("statvfs failed");
+ exit(1);
+ }
+
+ if (strcmp(buf.f_basetype, "zfs") == 0) {
+ pass = B_TRUE;
+ } else if (strcmp(buf.f_basetype, "tmpfs") == 0) {
+ pass = B_FALSE;
+ } else {
+ (void) printf("SKIP: expected 'zfs' or 'tmpfs'\n");
+ return;
+ }
+
+ fd = open(path, O_WRONLY | O_CREAT | O_EXCL | O_DIRECT, 0644);
+ if (fd >= 0) {
+ (void) close(fd);
+ (void) unlink(path);
+ if (!pass) {
+ (void) printf("FAILED: O_DIRECT on %s/tst_open is "
+ "expected to fail\n", dir);
+ exit(1);
+ }
+ } else {
+ if (pass) {
+ (void) printf("FAILED: O_DIRECT on %s/tst_open is "
+ "expected to succeed\n", dir);
+ exit(1);
+ }
+
+ if (errno != EINVAL) {
+ (void) printf("FAILED: expected EINVAL, got %d\n",
+ errno);
+ exit(1);
+ }
+ }
+}
+
+int
+main(void)
+{
+ /* On typical illumos distros, /tmp is tmpfs, O_DIRECT should fail */
+ o_direct_test("/tmp");
+
+ /* On typical illumos distros, /var is zfs, O_DIRECT should pass */
+ o_direct_test("/var/tmp");
+
+ (void) printf("PASS\n");
+ return (0);
+}
diff --git a/usr/src/uts/common/fs/vnode.c b/usr/src/uts/common/fs/vnode.c
index c57884a940..3babdbecdb 100644
--- a/usr/src/uts/common/fs/vnode.c
+++ b/usr/src/uts/common/fs/vnode.c
@@ -51,6 +51,7 @@
#include <sys/vfs.h>
#include <sys/vfs_opreg.h>
#include <sys/vnode.h>
+#include <sys/filio.h>
#include <sys/rwstlock.h>
#include <sys/fem.h>
#include <sys/stat.h>
@@ -1254,6 +1255,22 @@ top:
if ((error = VOP_SETATTR(vp, &vattr, 0, CRED(), NULL)) != 0)
goto out;
}
+
+ /*
+ * Turn on directio, if requested.
+ */
+ if (filemode & FDIRECT) {
+ if ((error = VOP_IOCTL(vp, _FIODIRECTIO, DIRECTIO_ON, 0,
+ CRED(), NULL, NULL)) != 0) {
+ /*
+ * On Linux, O_DIRECT returns EINVAL when the file
+ * system does not support directio, so we'll do the
+ * same.
+ */
+ error = EINVAL;
+ goto out;
+ }
+ }
out:
ASSERT(vp->v_count > 0);
diff --git a/usr/src/uts/common/sys/fcntl.h b/usr/src/uts/common/sys/fcntl.h
index cf55ebbf2a..4af23583fd 100644
--- a/usr/src/uts/common/sys/fcntl.h
+++ b/usr/src/uts/common/sys/fcntl.h
@@ -37,7 +37,7 @@
*/
/* Copyright (c) 2013, OmniTI Computer Consulting, Inc. All rights reserved. */
-/* Copyright 2015, Joyent, Inc. */
+/* Copyright 2020 Joyent, Inc. */
#ifndef _SYS_FCNTL_H
#define _SYS_FCNTL_H
@@ -89,6 +89,9 @@ extern "C" {
#if !defined(_STRICT_SYMBOLS) || defined(_XPG7)
#define O_DIRECTORY 0x1000000 /* fail if not a directory */
#endif
+#if !defined(_STRICT_SYMBOLS)
+#define O_DIRECT 0x2000000 /* direct disk access hint */
+#endif
/*
* fcntl(2) requests
diff --git a/usr/src/uts/common/sys/file.h b/usr/src/uts/common/sys/file.h
index f544033d2f..c7d67a5d47 100644
--- a/usr/src/uts/common/sys/file.h
+++ b/usr/src/uts/common/sys/file.h
@@ -27,7 +27,7 @@
/* All Rights Reserved */
/* Copyright (c) 2013, OmniTI Computer Consulting, Inc. All rights reserved. */
-/* Copyright 2017 Joyent, Inc. */
+/* Copyright 2020 Joyent, Inc. */
#ifndef _SYS_FILE_H
#define _SYS_FILE_H
@@ -119,6 +119,7 @@ typedef struct fpollinfo {
#define FCLOEXEC 0x800000 /* O_CLOEXEC = 0x800000 */
#define FDIRECTORY 0x1000000 /* O_DIRECTORY = 0x1000000 */
+#define FDIRECT 0x2000000 /* O_DIRECT = 0x2000000 */
#if defined(_KERNEL) || defined(_FAKE_KERNEL)