/*
 * 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));
	}
}
