1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24 */ 25 26 #include <stdio.h> 27 #include <stdlib.h> 28 #include <unistd.h> 29 #include <limits.h> 30 #include <errno.h> 31 #include <fcntl.h> 32 #include <sys/types.h> 33 #include <sys/fcntl.h> 34 #include <sys/stat.h> 35 #include <sys/statvfs.h> 36 #include <sys/errno.h> 37 #include <sys/time.h> 38 #include <sys/ioctl.h> 39 #include <sys/wait.h> 40 #include <sys/param.h> 41 #include <string.h> 42 43 #define FSIZE 256*1024*1024 44 #define BSIZE 512 45 46 /* Initialize Globals */ 47 static long fsize = FSIZE; 48 static size_t bsize = BSIZE; 49 static int count = 0; 50 static int rflag = 0; 51 static int seed = 0; 52 static int vflag = 0; 53 static int errflag = 0; 54 static off_t offset = 0; 55 static char *filename = NULL; 56 57 static void usage(char *execname); 58 static void parse_options(int argc, char *argv[]); 59 static void do_write(int fd); 60 static void do_trunc(int fd); 61 62 static void 63 usage(char *execname) 64 { 65 (void) fprintf(stderr, 66 "usage: %s [-b blocksize] [-c count] [-f filesize]" 67 " [-o offset] [-s seed] [-r] [-v] filename\n", execname); 68 (void) exit(1); 69 } 70 71 int 72 main(int argc, char *argv[]) 73 { 74 int i = 0; 75 int fd = -1; 76 77 parse_options(argc, argv); 78 79 fd = open(filename, O_RDWR|O_CREAT|O_TRUNC, 0666); 80 if (fd < 0) { 81 perror("open"); 82 exit(3); 83 } 84 85 while (i < count) { 86 (void) do_write(fd); 87 (void) do_trunc(fd); 88 89 i++; 90 } 91 92 (void) close(fd); 93 return (0); 94 } 95 96 static void 97 parse_options(int argc, char *argv[]) 98 { 99 int c; 100 101 extern char *optarg; 102 extern int optind, optopt; 103 104 count = fsize / bsize; 105 seed = time(NULL); 106 while ((c = getopt(argc, argv, "b:c:f:o:rs:v")) != -1) { 107 switch (c) { 108 case 'b': 109 bsize = atoi(optarg); 110 break; 111 112 case 'c': 113 count = atoi(optarg); 114 break; 115 116 case 'f': 117 fsize = atoi(optarg); 118 break; 119 120 case 'o': 121 offset = atoi(optarg); 122 break; 123 124 case 'r': 125 rflag++; 126 break; 127 128 case 's': 129 seed = atoi(optarg); 130 break; 131 132 case 'v': 133 vflag++; 134 break; 135 136 case ':': 137 (void) fprintf(stderr, 138 "Option -%c requires an operand\n", optopt); 139 errflag++; 140 break; 141 142 case '?': 143 (void) fprintf(stderr, 144 "Unrecognized option: -%c\n", optopt); 145 errflag++; 146 break; 147 } 148 149 if (errflag) { 150 (void) usage(argv[0]); 151 } 152 } 153 if (argc <= optind) { 154 (void) fprintf(stderr, 155 "No filename specified\n"); 156 usage(argv[0]); 157 } 158 filename = argv[optind]; 159 160 if (vflag) { 161 (void) fprintf(stderr, "Seed = %d\n", seed); 162 } 163 srandom(seed); 164 } 165 166 static void 167 do_write(int fd) 168 { 169 off_t roffset = 0; 170 char *buf = NULL; 171 char *rbuf = NULL; 172 173 buf = (char *)calloc(1, bsize); 174 rbuf = (char *)calloc(1, bsize); 175 if (buf == NULL || rbuf == NULL) { 176 perror("malloc"); 177 exit(4); 178 } 179 180 roffset = random() % fsize; 181 if (lseek64(fd, (offset + roffset), SEEK_SET) < 0) { 182 perror("lseek"); 183 exit(5); 184 } 185 186 buf = "SMBFS Test Suite Truncation Test"; 187 if (write(fd, buf, bsize) < bsize) { 188 perror("write"); 189 exit(6); 190 } 191 192 if (rflag) { 193 if (lseek64(fd, (offset + roffset), SEEK_SET) < 0) { 194 perror("lseek"); 195 exit(7); 196 } 197 198 if (read(fd, rbuf, bsize) < bsize) { 199 perror("read"); 200 exit(8); 201 } 202 203 if (memcmp(buf, rbuf, bsize) != 0) { 204 perror("memcmp"); 205 exit(9); 206 } 207 } 208 if (vflag) { 209 (void) fprintf(stderr, 210 "Wrote to offset %jd\n", (intmax_t)(offset + roffset)); 211 if (rflag) { 212 (void) fprintf(stderr, 213 "Read back from offset %jd\n", 214 (intmax_t)(offset + roffset)); 215 } 216 } 217 218 (void) free(buf); 219 (void) free(rbuf); 220 } 221 222 static void 223 do_trunc(int fd) 224 { 225 off_t roffset = 0; 226 227 roffset = random() % fsize; 228 if (ftruncate64(fd, (offset + roffset)) < 0) { 229 perror("truncate"); 230 exit(7); 231 } 232 233 if (vflag) { 234 (void) fprintf(stderr, 235 "Truncated at offset %jd\n", 236 (intmax_t)(offset + roffset)); 237 } 238 } 239