aboutsummaryrefslogtreecommitdiffstats
path: root/tests/zfs-tests
diff options
context:
space:
mode:
authorBrian Atkinson <[email protected]>2022-05-11 11:38:16 -0400
committerGitHub <[email protected]>2022-05-11 08:38:16 -0700
commitf567d67fdae5819ec25048a8b5d648fc14e6defe (patch)
treeba363c6553002896fa361f5383406042c435fce6 /tests/zfs-tests
parent3ed04d66aa440ee3e2c38d639a26f11d568e387d (diff)
Adding ZTS test for O_APPEND
Commit 63b18e4 fixed an issue in zpl_aio_write() to make sure that kiocb->ki_pos was updated correctly when opening a file with O_APPEND. Adding a test to verify O_APPEND functionality with lseek can make sure that all other distros/kernel versions also have the correct behavior. Also moved the threadappends_001_pos test into this append test directory in functional ZTS directory. This way the two append tests are together for organization purposes. Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Brian Atkinson <[email protected]> Closes #13424
Diffstat (limited to 'tests/zfs-tests')
-rw-r--r--tests/zfs-tests/cmd/.gitignore1
-rw-r--r--tests/zfs-tests/cmd/Makefile.am4
-rw-r--r--tests/zfs-tests/cmd/file/file_append.c206
-rw-r--r--tests/zfs-tests/include/commands.cfg1
-rw-r--r--tests/zfs-tests/tests/Makefile.am7
-rwxr-xr-xtests/zfs-tests/tests/functional/append/cleanup.ksh (renamed from tests/zfs-tests/tests/functional/threadsappend/cleanup.ksh)9
-rwxr-xr-xtests/zfs-tests/tests/functional/append/file_append.ksh73
-rwxr-xr-xtests/zfs-tests/tests/functional/append/setup.ksh (renamed from tests/zfs-tests/tests/functional/threadsappend/setup.ksh)7
-rwxr-xr-xtests/zfs-tests/tests/functional/append/threadsappend_001_pos.ksh (renamed from tests/zfs-tests/tests/functional/threadsappend/threadsappend_001_pos.ksh)0
-rw-r--r--tests/zfs-tests/tests/functional/threadsappend/.gitignore1
10 files changed, 290 insertions, 19 deletions
diff --git a/tests/zfs-tests/cmd/.gitignore b/tests/zfs-tests/cmd/.gitignore
index 9de5687d6..1830cab76 100644
--- a/tests/zfs-tests/cmd/.gitignore
+++ b/tests/zfs-tests/cmd/.gitignore
@@ -4,6 +4,7 @@
/devname2devid
/dir_rd_update
/draid
+/file_append
/file_check
/file_trunc
/file_write
diff --git a/tests/zfs-tests/cmd/Makefile.am b/tests/zfs-tests/cmd/Makefile.am
index b5609b523..71edd4939 100644
--- a/tests/zfs-tests/cmd/Makefile.am
+++ b/tests/zfs-tests/cmd/Makefile.am
@@ -41,9 +41,9 @@ scripts_zfs_tests_bin_PROGRAMS += %D%/draid
libnvpair.la
%C%_draid_LDADD += $(ZLIB_LIBS)
-
EXTRA_DIST += $(addprefix %D%/,file/file_common.h)
-scripts_zfs_tests_bin_PROGRAMS += %D%/file_check %D%/file_trunc %D%/file_write %D%/largest_file %D%/randwritecomp
+scripts_zfs_tests_bin_PROGRAMS += %D%/file_append %D%/file_check %D%/file_trunc %D%/file_write %D%/largest_file %D%/randwritecomp
+%C%_file_append_SOURCES = %D%/file/file_append.c
%C%_file_check_SOURCES = %D%/file/file_check.c
%C%_file_trunc_SOURCES = %D%/file/file_trunc.c
%C%_file_write_SOURCES = %D%/file/file_write.c
diff --git a/tests/zfs-tests/cmd/file/file_append.c b/tests/zfs-tests/cmd/file/file_append.c
new file mode 100644
index 000000000..32433e4fa
--- /dev/null
+++ b/tests/zfs-tests/cmd/file/file_append.c
@@ -0,0 +1,206 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2022 by Triad National Security, LLC
+ */
+
+#include "file_common.h"
+#include <unistd.h>
+#include <sys/sysmacros.h>
+
+static char *filename = NULL;
+static int expected_offset = -1;
+static int blocksize = 131072; /* 128KiB */
+static int numblocks = 8;
+static const char *execname = "file_append";
+static int use_odirect = 0;
+
+static void
+usage(void)
+{
+ (void) fprintf(stderr,
+ "usage %s -f filename -e expected_offset [-b blocksize] \n"
+ " [-n numblocks] [-d use_odirect] [-h help]\n"
+ "\n"
+ "Opens a file using O_APPEND and writes numblocks blocksize\n"
+ "blocks to filename.\n"
+ "Checks if expected_offst == lseek(fd, 0, SEEK_CUR)).\n"
+ "\n"
+ " filename: File to open with O_APPEND and write to.\n"
+ " expected_offset: Expected file offset after writing\n"
+ " blocksize numblocks to filename\n"
+ " blocksize: Size of each block to writei (must be at\n"
+ " least >= 512). If using use_odirect (-d)\n"
+ " must be a mutltiple of _SC_PAGE_SIZE\n"
+ " numblocks: Total number of blocksized blocks to\n"
+ " write.\n"
+ " use_odirect: Open file using O_DIRECT.\n"
+ " help: Print usage information and exit.\n"
+ "\n"
+ " Required parameters:\n"
+ " filename\n"
+ " expected_offset\n"
+ "\n"
+ " Default values:\n"
+ " blocksize -> 131072 (128 KiB)\n"
+ " numblocks -> 8\n"
+ " use_odirect -> False\n",
+ execname);
+ (void) exit(1);
+}
+
+static void
+parse_options(int argc, char *argv[])
+{
+ int c;
+ int errflag = 0;
+ extern char *optarg;
+ extern int optind, optopt;
+
+ while ((c = getopt(argc, argv, "b:de:f:hn:")) != -1) {
+ switch (c) {
+ case 'b':
+ blocksize = atoi(optarg);
+ break;
+ case 'd':
+ use_odirect = 1;
+ break;
+ case 'e':
+ expected_offset = atoi(optarg);
+ break;
+ case 'f':
+ filename = optarg;
+ break;
+ case 'h':
+ (void) usage();
+ break;
+ case 'n':
+ numblocks = atoi(optarg);
+ break;
+ case ':':
+ (void) fprintf(stderr,
+ "Option -%c requires an operand\n",
+ optopt);
+ errflag++;
+ break;
+ case '?':
+ default:
+ (void) fprintf(stderr,
+ "Unrecognized option: -%c\n", optopt);
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag)
+ (void) usage();
+
+ if (use_odirect && ((blocksize % sysconf(_SC_PAGE_SIZE)) != 0)) {
+ (void) fprintf(stderr,
+ "blocksize parameter invalid when using O_DIRECT.\n");
+ (void) usage();
+ }
+
+ if (blocksize < 512 || expected_offset < 0 || filename == NULL ||
+ numblocks <= 0) {
+ (void) fprintf(stderr,
+ "Required parameters(s) missing or invalid value for "
+ "parameter.\n");
+ (void) usage();
+ }
+}
+
+int
+main(int argc, char *argv[])
+{
+ int err;
+ const char *datapattern = "0xf00ba3";
+ int fd = -1;
+ int fd_flags = O_WRONLY | O_CREAT | O_APPEND;
+ int buf_offset = 0;
+ char *buf;
+
+ parse_options(argc, argv);
+
+ if (use_odirect)
+ fd_flags |= O_DIRECT;
+
+ fd = open(filename, fd_flags, 0666);
+ if (fd == -1) {
+ (void) fprintf(stderr, "%s: %s: ", execname, filename);
+ perror("open");
+ (void) exit(2);
+ }
+
+ err = posix_memalign((void **)&buf, sysconf(_SC_PAGE_SIZE),
+ blocksize);
+
+ if (err != 0) {
+ (void) fprintf(stderr,
+ "%s: %s\n", execname, strerror(err));
+ (void) exit(2);
+ }
+
+ /* Putting known data pattern in buffer */
+ int left = blocksize;
+ while (left) {
+ size_t amt = MIN(strlen(datapattern), left);
+ memcpy(&buf[buf_offset], datapattern, amt);
+ buf_offset += amt;
+ left -= amt;
+ }
+
+ for (int i = 0; i < numblocks; i++) {
+ int wrote = write(fd, buf, blocksize);
+
+ if (wrote != blocksize) {
+ if (wrote < 0) {
+ perror("write");
+ } else {
+ (void) fprintf(stderr,
+ "%s: unexpected short write, wrote %d "
+ "byte, expected %d\n", execname, wrote,
+ blocksize);
+ }
+ (void) exit(2);
+ }
+ }
+
+ /* Getting current file offset */
+ off_t off = lseek(fd, 0, SEEK_CUR);
+
+ if (off == -1) {
+ perror("output seek");
+ (void) exit(2);
+ } else if (off != expected_offset) {
+ (void) fprintf(stderr,
+ "%s: expected offset %d but current offset in %s is set "
+ "to %ld\n", execname, expected_offset, filename,
+ (long int)off);
+ (void) exit(2);
+ }
+
+ (void) close(fd);
+ free(buf);
+
+ return (0);
+}
diff --git a/tests/zfs-tests/include/commands.cfg b/tests/zfs-tests/include/commands.cfg
index 13110ed4f..9dc2b4d0e 100644
--- a/tests/zfs-tests/include/commands.cfg
+++ b/tests/zfs-tests/include/commands.cfg
@@ -179,6 +179,7 @@ export ZFSTEST_FILES='badsend
devname2devid
dir_rd_update
draid
+ file_append
file_check
file_trunc
file_write
diff --git a/tests/zfs-tests/tests/Makefile.am b/tests/zfs-tests/tests/Makefile.am
index 355ad727d..2202d9026 100644
--- a/tests/zfs-tests/tests/Makefile.am
+++ b/tests/zfs-tests/tests/Makefile.am
@@ -385,6 +385,10 @@ nobase_dist_datadir_zfs_tests_tests_SCRIPTS += \
functional/alloc_class/alloc_class_013_pos.ksh \
functional/alloc_class/cleanup.ksh \
functional/alloc_class/setup.ksh \
+ functional/append/file_append.ksh \
+ functional/append/threadsappend_001_pos.ksh \
+ functional/append/cleanup.ksh \
+ functional/append/setup.ksh \
functional/arc/arcstats_runtime_tuning.ksh \
functional/arc/cleanup.ksh \
functional/arc/dbufstats_001_pos.ksh \
@@ -1842,9 +1846,6 @@ nobase_dist_datadir_zfs_tests_tests_SCRIPTS += \
functional/suid/suid_write_to_suid.ksh \
functional/suid/suid_write_to_suid_sgid.ksh \
functional/suid/suid_write_zil_replay.ksh \
- functional/threadsappend/cleanup.ksh \
- functional/threadsappend/setup.ksh \
- functional/threadsappend/threadsappend_001_pos.ksh \
functional/trim/autotrim_config.ksh \
functional/trim/autotrim_integrity.ksh \
functional/trim/autotrim_trim_integrity.ksh \
diff --git a/tests/zfs-tests/tests/functional/threadsappend/cleanup.ksh b/tests/zfs-tests/tests/functional/append/cleanup.ksh
index 3166bd6ec..307feabd1 100755
--- a/tests/zfs-tests/tests/functional/threadsappend/cleanup.ksh
+++ b/tests/zfs-tests/tests/functional/append/cleanup.ksh
@@ -21,14 +21,9 @@
#
#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
+# Copyright (c) 2022 by Triad National Security, LCC
#
-#
-# Copyright (c) 2013 by Delphix. All rights reserved.
-#
-
-. $STF_SUITE/include/libtest.shlib
+. ${STF_SUITE}/include/libtest.shlib
default_cleanup
diff --git a/tests/zfs-tests/tests/functional/append/file_append.ksh b/tests/zfs-tests/tests/functional/append/file_append.ksh
new file mode 100755
index 000000000..b40d10c05
--- /dev/null
+++ b/tests/zfs-tests/tests/functional/append/file_append.ksh
@@ -0,0 +1,73 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2022 by Triad National Security, LCC
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+#
+# DESCRIPTION:
+# Tests file offset using O_APPEND.
+#
+# STRATEGY:
+# 1. Open file using O_APPEND
+# 2. Write to the file using random number of blocks (1, 2, or 3)
+# 3. Verify that the file offset is correct using lseek after the write
+# 4. Repeat steps 2 and 3, 5 times
+# 5. Close the file.
+# 6. Repeat steps 1-5 but also open file with O_DIRECT
+#
+
+verify_runnable "global"
+
+log_assert "Ensure file offset is updated correctly when opened with O_APPEND"
+
+mntpt=$(get_prop mountpoint $TESTPOOL/$TESTFS)
+filename=$mntpt/append_file.txt
+bs=131072
+ITERATIONS=5
+expected=0
+
+# First test using buffered writes with O_APPEND
+for i in $(seq $ITERATIONS); do
+ num_blocks=$(random_int_between 1 3)
+ expected=$((expected + ( bs * num_blocks)))
+ log_must file_append -f $filename -e $expected -b $bs -n $num_blocks
+ curr_offset=$expected
+done
+
+log_must rm -f $filename
+
+expected=0
+
+# Repeat same test using O_DIRECT writes with O_APPEND
+for i in $(seq $ITERATIONS); do
+ num_blocks=$(random_int_between 1 3)
+ expected=$((expected + ( bs * num_blocks)))
+ log_must file_append -f $filename -e $expected -b $bs -n $num_blocks -d
+done
+
+log_must rm -f $filename
+
+log_pass "File offset updated correctly when opening a file with O_APPEND."
diff --git a/tests/zfs-tests/tests/functional/threadsappend/setup.ksh b/tests/zfs-tests/tests/functional/append/setup.ksh
index 4fc55cd47..e692d7b1b 100755
--- a/tests/zfs-tests/tests/functional/threadsappend/setup.ksh
+++ b/tests/zfs-tests/tests/functional/append/setup.ksh
@@ -21,12 +21,7 @@
#
#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-#
-# Copyright (c) 2013 by Delphix. All rights reserved.
+# Copyright (c) 2022 by Triad National Security, LCC
#
. $STF_SUITE/include/libtest.shlib
diff --git a/tests/zfs-tests/tests/functional/threadsappend/threadsappend_001_pos.ksh b/tests/zfs-tests/tests/functional/append/threadsappend_001_pos.ksh
index 8154214a0..8154214a0 100755
--- a/tests/zfs-tests/tests/functional/threadsappend/threadsappend_001_pos.ksh
+++ b/tests/zfs-tests/tests/functional/append/threadsappend_001_pos.ksh
diff --git a/tests/zfs-tests/tests/functional/threadsappend/.gitignore b/tests/zfs-tests/tests/functional/threadsappend/.gitignore
deleted file mode 100644
index 4c8c8cdf3..000000000
--- a/tests/zfs-tests/tests/functional/threadsappend/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-/threadsappend