diff options
author | Brian Atkinson <[email protected]> | 2022-05-11 11:38:16 -0400 |
---|---|---|
committer | GitHub <[email protected]> | 2022-05-11 08:38:16 -0700 |
commit | f567d67fdae5819ec25048a8b5d648fc14e6defe (patch) | |
tree | ba363c6553002896fa361f5383406042c435fce6 /tests/zfs-tests | |
parent | 3ed04d66aa440ee3e2c38d639a26f11d568e387d (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/.gitignore | 1 | ||||
-rw-r--r-- | tests/zfs-tests/cmd/Makefile.am | 4 | ||||
-rw-r--r-- | tests/zfs-tests/cmd/file/file_append.c | 206 | ||||
-rw-r--r-- | tests/zfs-tests/include/commands.cfg | 1 | ||||
-rw-r--r-- | tests/zfs-tests/tests/Makefile.am | 7 | ||||
-rwxr-xr-x | tests/zfs-tests/tests/functional/append/cleanup.ksh (renamed from tests/zfs-tests/tests/functional/threadsappend/cleanup.ksh) | 9 | ||||
-rwxr-xr-x | tests/zfs-tests/tests/functional/append/file_append.ksh | 73 | ||||
-rwxr-xr-x | tests/zfs-tests/tests/functional/append/setup.ksh (renamed from tests/zfs-tests/tests/functional/threadsappend/setup.ksh) | 7 | ||||
-rwxr-xr-x | tests/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/.gitignore | 1 |
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 |