diff options
Diffstat (limited to 'sys/contrib/openzfs/tests/zfs-tests/cmd/file_trunc/file_trunc.c')
-rw-r--r-- | sys/contrib/openzfs/tests/zfs-tests/cmd/file_trunc/file_trunc.c | 240 |
1 files changed, 240 insertions, 0 deletions
diff --git a/sys/contrib/openzfs/tests/zfs-tests/cmd/file_trunc/file_trunc.c b/sys/contrib/openzfs/tests/zfs-tests/cmd/file_trunc/file_trunc.c new file mode 100644 index 000000000000..69096752efa2 --- /dev/null +++ b/sys/contrib/openzfs/tests/zfs-tests/cmd/file_trunc/file_trunc.c @@ -0,0 +1,240 @@ +/* + * 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 2007 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* + * Copyright (c) 2012, 2014 by Delphix. All rights reserved. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <limits.h> +#include <errno.h> +#include <fcntl.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/statvfs.h> +#include <sys/time.h> +#include <sys/ioctl.h> +#include <sys/wait.h> +#include <sys/param.h> +#include <string.h> +#include <time.h> +#include <inttypes.h> + +#define FSIZE 256*1024*1024 +#define BSIZE 512 + +/* Initialize Globals */ +static long fsize = FSIZE; +static size_t bsize = BSIZE; +static int count = 0; +static int rflag = 0; +static int seed = 0; +static int vflag = 0; +static int errflag = 0; +static off_t offset = 0; +static char *filename = NULL; + +static void usage(char *execname); +static void parse_options(int argc, char *argv[]); +static void do_write(int fd); +static void do_trunc(int fd); + +static void +usage(char *execname) +{ + (void) fprintf(stderr, + "usage: %s [-b blocksize] [-c count] [-f filesize]" + " [-o offset] [-s seed] [-r] [-v] filename\n", execname); + (void) exit(1); +} + +int +main(int argc, char *argv[]) +{ + int i = 0; + int fd = -1; + + parse_options(argc, argv); + + fd = open(filename, O_RDWR|O_CREAT|O_TRUNC, 0666); + if (fd < 0) { + perror("open"); + exit(3); + } + + for (i = 0; count == 0 || i < count; i++) { + (void) do_write(fd); + (void) do_trunc(fd); + } + + (void) close(fd); + return (0); +} + +static void +parse_options(int argc, char *argv[]) +{ + int c; + + extern char *optarg; + extern int optind, optopt; + + count = fsize / bsize; + seed = time(NULL); + while ((c = getopt(argc, argv, "b:c:f:o:rs:v")) != -1) { + switch (c) { + case 'b': + bsize = atoi(optarg); + break; + + case 'c': + count = atoi(optarg); + break; + + case 'f': + fsize = atoi(optarg); + break; + + case 'o': + offset = atoi(optarg); + break; + + case 'r': + rflag++; + break; + + case 's': + seed = atoi(optarg); + break; + + case 'v': + vflag++; + break; + + case ':': + (void) fprintf(stderr, + "Option -%c requires an operand\n", optopt); + errflag++; + break; + + case '?': + (void) fprintf(stderr, + "Unrecognized option: -%c\n", optopt); + errflag++; + break; + } + + if (errflag) { + (void) usage(argv[0]); + } + } + if (argc <= optind) { + (void) fprintf(stderr, + "No filename specified\n"); + usage(argv[0]); + } + filename = argv[optind]; + + if (vflag) { + (void) fprintf(stderr, "Seed = %d\n", seed); + } + srandom(seed); +} + +static void +do_write(int fd) +{ + off_t roffset = 0; + char *buf = NULL; + char *rbuf = NULL; + + buf = (char *)calloc(1, bsize); + rbuf = (char *)calloc(1, bsize); + if (buf == NULL || rbuf == NULL) { + perror("malloc"); + exit(4); + } + + roffset = random() % fsize; + if (lseek64(fd, (offset + roffset), SEEK_SET) < 0) { + perror("lseek"); + exit(5); + } + + (void) strcpy(buf, "ZFS Test Suite Truncation Test"); + if (write(fd, buf, bsize) < bsize) { + perror("write"); + exit(6); + } + + if (rflag) { + if (lseek64(fd, (offset + roffset), SEEK_SET) < 0) { + perror("lseek"); + exit(7); + } + + if (read(fd, rbuf, bsize) < bsize) { + perror("read"); + exit(8); + } + + if (memcmp(buf, rbuf, bsize) != 0) { + perror("memcmp"); + exit(9); + } + } + if (vflag) { + (void) fprintf(stderr, + "Wrote to offset %" PRId64 "\n", (offset + roffset)); + if (rflag) { + (void) fprintf(stderr, + "Read back from offset %" PRId64 "\n", + (offset + roffset)); + } + } + + (void) free(buf); + (void) free(rbuf); +} + +static void +do_trunc(int fd) +{ + off_t roffset = 0; + + roffset = random() % fsize; + if (ftruncate64(fd, (offset + roffset)) < 0) { + perror("truncate"); + exit(7); + } + + if (vflag) { + (void) fprintf(stderr, "Truncated at offset %" PRId64 "\n", + (offset + roffset)); + } +} |