diff options
Diffstat (limited to 'tests/zfs-tests/cmd/file/randfree_file.c')
-rw-r--r-- | tests/zfs-tests/cmd/file/randfree_file.c | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/tests/zfs-tests/cmd/file/randfree_file.c b/tests/zfs-tests/cmd/file/randfree_file.c new file mode 100644 index 000000000..e00780cd2 --- /dev/null +++ b/tests/zfs-tests/cmd/file/randfree_file.c @@ -0,0 +1,125 @@ +/* + * 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 by Delphix. All rights reserved. + */ + +#include "file_common.h" +#include <sys/types.h> +#include <unistd.h> +#include <fcntl.h> +#include <string.h> +#include <linux/falloc.h> + +/* + * Create a file with assigned size and then free the specified + * section of the file + */ + +static void usage(char *progname); + +static void +usage(char *progname) +{ + (void) fprintf(stderr, + "usage: %s [-l filesize] [-s start-offset]" + "[-n section-len] filename\n", progname); + exit(1); +} + +int +main(int argc, char *argv[]) +{ + char *filename = NULL; + char *buf = NULL; + size_t filesize = 0; + off_t start_off = 0; + off_t off_len = 0; + int fd, ch; + mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; + + while ((ch = getopt(argc, argv, "l:s:n:")) != EOF) { + switch (ch) { + case 'l': + filesize = atoll(optarg); + break; + case 's': + start_off = atoll(optarg); + break; + case 'n': + off_len = atoll(optarg); + break; + default: + usage(argv[0]); + break; + } + } + + if (optind == argc - 1) + filename = argv[optind]; + else + usage(argv[0]); + + if ((fd = open(filename, O_RDWR | O_CREAT | O_TRUNC, mode)) < 0) { + perror("open"); + return (1); + } + + buf = (char *)calloc(1, filesize); + if (buf == NULL) { + perror("write"); + close(fd); + return (1); + } + memset(buf, 'c', filesize); + + if (write(fd, buf, filesize) < filesize) { + free(buf); + perror("write"); + close(fd); + return (1); + } + + free(buf); + +#if defined(FALLOC_FL_PUNCH_HOLE) && defined(FALLOC_FL_KEEP_SIZE) + if (fallocate(fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, + start_off, off_len) < 0) { + perror("fallocate"); + close(fd); + return (1); + } +#else /* !(defined(FALLOC_FL_PUNCH_HOLE) && defined(FALLOC_FL_KEEP_SIZE)) */ + { + perror("FALLOC_FL_PUNCH_HOLE unsupported"); + close(fd); + return (1); + } +#endif /* defined(FALLOC_FL_PUNCH_HOLE) && defined(FALLOC_FL_KEEP_SIZE) */ + close(fd); + return (0); +} |