1 /* 2 * Copyright (c) 1983, 1989, 1993, 1994 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34 #ifndef lint 35 static const char copyright[] = 36 "@(#) Copyright (c) 1983, 1989, 1993, 1994\n\ 37 The Regents of the University of California. All rights reserved.\n"; 38 #endif /* not lint */ 39 40 #ifndef lint 41 #if 0 42 static char sccsid[] = "@(#)newfs.c 8.13 (Berkeley) 5/1/95"; 43 #endif 44 static const char rcsid[] = 45 "$FreeBSD$"; 46 #endif /* not lint */ 47 48 /* 49 * newfs: friendly front end to mkfs 50 */ 51 #include <sys/param.h> 52 #include <sys/stat.h> 53 #include <sys/disklabel.h> 54 #include <sys/file.h> 55 #include <sys/mount.h> 56 57 #include <ufs/ufs/dir.h> 58 #include <ufs/ufs/dinode.h> 59 #include <ufs/ffs/fs.h> 60 #include <ufs/ufs/ufsmount.h> 61 62 #include <ctype.h> 63 #include <err.h> 64 #include <errno.h> 65 #include <paths.h> 66 #include <stdio.h> 67 #include <stdlib.h> 68 #include <string.h> 69 #include <syslog.h> 70 #include <unistd.h> 71 72 #include <stdarg.h> 73 #include "newfs.h" 74 75 static void fatal(const char *fmt, ...) __printflike(1, 2); 76 static struct disklabel *getdisklabel(char *s, int fd); 77 78 #define COMPAT /* allow non-labeled disks */ 79 80 /* 81 * The following two constants set the default block and fragment sizes. 82 * Both constants must be a power of 2 and meet the following constraints: 83 * MINBSIZE <= DESBLKSIZE <= MAXBSIZE 84 * sectorsize <= DESFRAGSIZE <= DESBLKSIZE 85 * DESBLKSIZE / DESFRAGSIZE <= 8 86 */ 87 #define DFL_FRAGSIZE 2048 88 #define DFL_BLKSIZE 16384 89 90 /* 91 * Cylinder groups may have up to many cylinders. The actual 92 * number used depends upon how much information can be stored 93 * on a single cylinder. The default is to use as many as possible 94 * cylinders per group. 95 */ 96 #define DESCPG 65536 /* desired fs_cpg ("infinity") */ 97 98 /* 99 * MAXBLKPG determines the maximum number of data blocks which are 100 * placed in a single cylinder group. The default is one indirect 101 * block worth of data blocks. 102 */ 103 #define MAXBLKPG(bsize) ((bsize) / sizeof(daddr_t)) 104 105 /* 106 * Each file system has a number of inodes statically allocated. 107 * We allocate one inode slot per NFPI fragments, expecting this 108 * to be far more than we will ever need. 109 */ 110 #define NFPI 4 111 112 /* 113 * About the same time as the above, we knew what went where on the disks. 114 * no longer so, so kill the code which finds the different platters too... 115 * We do this by saying one head, with a lot of sectors on it. 116 * The number of sectors are used to determine the size of a cyl-group. 117 * Kirk suggested one or two meg per "cylinder" so we say two. 118 */ 119 #define NSECTORS 4096 /* number of sectors */ 120 121 int Nflag; /* run without writing file system */ 122 int Rflag; /* regression test */ 123 int Uflag; /* enable soft updates for file system */ 124 u_int fssize; /* file system size */ 125 u_int secpercyl = NSECTORS; /* sectors per cylinder */ 126 int sectorsize; /* bytes/sector */ 127 int realsectorsize; /* bytes/sector in hardware */ 128 int fsize = 0; /* fragment size */ 129 int bsize = 0; /* block size */ 130 int cpg = DESCPG; /* cylinders/cylinder group */ 131 int cpgflg; /* cylinders/cylinder group flag was given */ 132 int minfree = MINFREE; /* free space threshold */ 133 int opt = DEFAULTOPT; /* optimization preference (space or time) */ 134 int density; /* number of bytes per inode */ 135 int maxcontig = 0; /* max contiguous blocks to allocate */ 136 int maxbpg; /* maximum blocks per file in a cyl group */ 137 int avgfilesize = AVFILESIZ;/* expected average file size */ 138 int avgfilesperdir = AFPDIR;/* expected number of files per directory */ 139 int bbsize = BBSIZE; /* boot block size */ 140 int sbsize = SBSIZE; /* superblock size */ 141 static int t_or_u_flag = 0; /* user has specified -t or -u */ 142 #ifdef COMPAT 143 static char *disktype; 144 static int unlabeled; 145 #endif 146 147 static char device[MAXPATHLEN]; 148 static char *progname; 149 150 static void rewritelabel (char *s, int fd, register struct disklabel *lp); 151 static void usage (void); 152 153 int 154 main(int argc, char *argv[]) 155 { 156 struct partition *pp; 157 struct disklabel *lp; 158 struct partition oldpartition; 159 struct stat st; 160 struct statfs *mp; 161 char *cp, *s1, *s2, *special; 162 int ch, fsi, fso, len, n, vflag; 163 164 vflag = 0; 165 if ((progname = strrchr(*argv, '/'))) 166 ++progname; 167 else 168 progname = *argv; 169 170 while ((ch = getopt(argc, argv, 171 "NRS:T:Ua:b:c:e:f:g:h:i:m:o:s:u:v:")) != -1) 172 switch (ch) { 173 case 'N': 174 Nflag = 1; 175 break; 176 case 'R': 177 Rflag = 1; 178 break; 179 case 'S': 180 if ((sectorsize = atoi(optarg)) <= 0) 181 fatal("%s: bad sector size", optarg); 182 break; 183 #ifdef COMPAT 184 case 'T': 185 disktype = optarg; 186 break; 187 #endif 188 case 'U': 189 Uflag = 1; 190 break; 191 case 'a': 192 if ((maxcontig = atoi(optarg)) <= 0) 193 fatal("%s: bad maximum contiguous blocks", 194 optarg); 195 break; 196 case 'b': 197 if ((bsize = atoi(optarg)) < MINBSIZE) 198 fatal("%s: bad block size", optarg); 199 break; 200 case 'c': 201 if ((cpg = atoi(optarg)) <= 0) 202 fatal("%s: bad cylinders/group", optarg); 203 cpgflg++; 204 break; 205 case 'e': 206 if ((maxbpg = atoi(optarg)) <= 0) 207 fatal("%s: bad blocks per file in a cylinder group", 208 optarg); 209 break; 210 case 'f': 211 if ((fsize = atoi(optarg)) <= 0) 212 fatal("%s: bad fragment size", optarg); 213 break; 214 case 'g': 215 if ((avgfilesize = atoi(optarg)) <= 0) 216 fatal("%s: bad average file size", optarg); 217 break; 218 case 'h': 219 if ((avgfilesperdir = atoi(optarg)) <= 0) 220 fatal("%s: bad average files per dir", optarg); 221 break; 222 case 'i': 223 if ((density = atoi(optarg)) <= 0) 224 fatal("%s: bad bytes per inode", optarg); 225 break; 226 case 'm': 227 if ((minfree = atoi(optarg)) < 0 || minfree > 99) 228 fatal("%s: bad free space %%", optarg); 229 break; 230 case 'o': 231 if (strcmp(optarg, "space") == 0) 232 opt = FS_OPTSPACE; 233 else if (strcmp(optarg, "time") == 0) 234 opt = FS_OPTTIME; 235 else 236 fatal( 237 "%s: unknown optimization preference: use `space' or `time'", 238 optarg); 239 break; 240 case 's': 241 if ((fssize = atoi(optarg)) <= 0) 242 fatal("%s: bad file system size", optarg); 243 break; 244 case 'u': 245 t_or_u_flag++; 246 if ((n = atoi(optarg)) < 0) 247 fatal("%s: bad sectors/track", optarg); 248 secpercyl = n; 249 break; 250 case 'v': 251 vflag = 1; 252 break; 253 case '?': 254 default: 255 usage(); 256 } 257 argc -= optind; 258 argv += optind; 259 260 if (argc != 2 && argc != 1) 261 usage(); 262 263 special = argv[0]; 264 cp = strrchr(special, '/'); 265 if (cp == 0) { 266 /* 267 * No path prefix; try prefixing _PATH_DEV. 268 */ 269 snprintf(device, sizeof(device), "%s%s", _PATH_DEV, special); 270 special = device; 271 } 272 if (Nflag) 273 fso = -1; 274 else { 275 fso = open(special, O_WRONLY); 276 if (fso < 0) 277 fatal("%s: %s", special, strerror(errno)); 278 279 /* Bail if target special is mounted */ 280 n = getmntinfo(&mp, MNT_NOWAIT); 281 if (n == 0) 282 fatal("%s: getmntinfo: %s", special, strerror(errno)); 283 284 len = sizeof(_PATH_DEV) - 1; 285 s1 = special; 286 if (strncmp(_PATH_DEV, s1, len) == 0) 287 s1 += len; 288 289 while (--n >= 0) { 290 s2 = mp->f_mntfromname; 291 if (strncmp(_PATH_DEV, s2, len) == 0) { 292 s2 += len - 1; 293 *s2 = 'r'; 294 } 295 if (strcmp(s1, s2) == 0 || strcmp(s1, &s2[1]) == 0) 296 fatal("%s is mounted on %s", 297 special, mp->f_mntonname); 298 ++mp; 299 } 300 } 301 fsi = open(special, O_RDONLY); 302 if (fsi < 0) 303 fatal("%s: %s", special, strerror(errno)); 304 if (fstat(fsi, &st) < 0) 305 fatal("%s: %s", special, strerror(errno)); 306 if ((st.st_mode & S_IFMT) != S_IFCHR) 307 printf("%s: %s: not a character-special device\n", 308 progname, special); 309 cp = strchr(argv[0], '\0'); 310 if (cp == argv[0]) 311 fatal("null special file name"); 312 cp--; 313 if (!vflag && (*cp < 'a' || *cp > 'h') && !isdigit(*cp)) 314 fatal("%s: can't figure out file system partition", 315 argv[0]); 316 #ifdef COMPAT 317 if (disktype == NULL) 318 disktype = argv[1]; 319 #endif 320 lp = getdisklabel(special, fsi); 321 if (vflag || isdigit(*cp)) 322 pp = &lp->d_partitions[0]; 323 else 324 pp = &lp->d_partitions[*cp - 'a']; 325 if (pp->p_size == 0) 326 fatal("%s: `%c' partition is unavailable", 327 argv[0], *cp); 328 if (pp->p_fstype == FS_BOOT) 329 fatal("%s: `%c' partition overlaps boot program", 330 argv[0], *cp); 331 if (fssize == 0) 332 fssize = pp->p_size; 333 if (fssize > pp->p_size) 334 fatal( 335 "%s: maximum file system size on the `%c' partition is %d", 336 argv[0], *cp, pp->p_size); 337 if (secpercyl == 0) { 338 secpercyl = lp->d_nsectors; 339 if (secpercyl <= 0) 340 fatal("%s: no default #sectors/track", argv[0]); 341 } 342 if (sectorsize == 0) { 343 sectorsize = lp->d_secsize; 344 if (sectorsize <= 0) 345 fatal("%s: no default sector size", argv[0]); 346 } 347 if (fsize == 0) { 348 fsize = pp->p_fsize; 349 if (fsize <= 0) 350 fsize = MAX(DFL_FRAGSIZE, lp->d_secsize); 351 } 352 if (bsize == 0) { 353 bsize = pp->p_frag * pp->p_fsize; 354 if (bsize <= 0) 355 bsize = MIN(DFL_BLKSIZE, 8 * fsize); 356 } 357 /* 358 * Maxcontig sets the default for the maximum number of blocks 359 * that may be allocated sequentially. With filesystem clustering 360 * it is possible to allocate contiguous blocks up to the maximum 361 * transfer size permitted by the controller or buffering. 362 */ 363 if (maxcontig == 0) 364 maxcontig = MAX(1, MAXPHYS / bsize - 1); 365 if (density == 0) 366 density = NFPI * fsize; 367 if (minfree < MINFREE && opt != FS_OPTSPACE) { 368 fprintf(stderr, "Warning: changing optimization to space "); 369 fprintf(stderr, "because minfree is less than %d%%\n", MINFREE); 370 opt = FS_OPTSPACE; 371 } 372 /* 373 * Only complain if -t or -u have been specified; the default 374 * case (4096 sectors per cylinder) is intended to disagree 375 * with the disklabel. 376 */ 377 if (t_or_u_flag && secpercyl != lp->d_secpercyl) 378 fprintf(stderr, "%s (%d) %s (%lu)\n", 379 "Warning: calculated sectors per cylinder", secpercyl, 380 "disagrees with disk label", (u_long)lp->d_secpercyl); 381 if (maxbpg == 0) 382 maxbpg = MAXBLKPG(bsize); 383 #ifdef notdef /* label may be 0 if faked up by kernel */ 384 bbsize = lp->d_bbsize; 385 sbsize = lp->d_sbsize; 386 #endif 387 oldpartition = *pp; 388 realsectorsize = sectorsize; 389 if (sectorsize != DEV_BSIZE) { /* XXX */ 390 int secperblk = sectorsize / DEV_BSIZE; 391 392 sectorsize = DEV_BSIZE; 393 secpercyl *= secperblk; 394 fssize *= secperblk; 395 pp->p_size *= secperblk; 396 } 397 mkfs(pp, special, fsi, fso); 398 if (realsectorsize != DEV_BSIZE) 399 pp->p_size /= realsectorsize /DEV_BSIZE; 400 if (!Nflag && bcmp(pp, &oldpartition, sizeof(oldpartition))) 401 rewritelabel(special, fso, lp); 402 if (!Nflag) 403 close(fso); 404 close(fsi); 405 exit(0); 406 } 407 408 #ifdef COMPAT 409 const char lmsg[] = "%s: can't read disk label; disk type must be specified"; 410 #else 411 const char lmsg[] = "%s: can't read disk label"; 412 #endif 413 414 struct disklabel * 415 getdisklabel(char *s, int fd) 416 { 417 static struct disklabel lab; 418 419 if (ioctl(fd, DIOCGDINFO, (char *)&lab) < 0) { 420 #ifdef COMPAT 421 if (disktype) { 422 struct disklabel *lp; 423 424 unlabeled++; 425 lp = getdiskbyname(disktype); 426 if (lp == NULL) 427 fatal("%s: unknown disk type", disktype); 428 return (lp); 429 } 430 #endif 431 warn("ioctl (GDINFO)"); 432 fatal(lmsg, s); 433 } 434 return (&lab); 435 } 436 437 void 438 rewritelabel(char *s, int fd, struct disklabel *lp) 439 { 440 #ifdef COMPAT 441 if (unlabeled) 442 return; 443 #endif 444 lp->d_checksum = 0; 445 lp->d_checksum = dkcksum(lp); 446 if (ioctl(fd, DIOCWDINFO, (char *)lp) < 0) { 447 warn("ioctl (WDINFO)"); 448 fatal("%s: can't rewrite disk label", s); 449 } 450 } 451 452 /*VARARGS*/ 453 void 454 fatal(const char *fmt, ...) 455 { 456 va_list ap; 457 458 va_start(ap, fmt); 459 if (fcntl(STDERR_FILENO, F_GETFL) < 0) { 460 openlog(progname, LOG_CONS, LOG_DAEMON); 461 vsyslog(LOG_ERR, fmt, ap); 462 closelog(); 463 } else 464 vwarnx(fmt, ap); 465 va_end(ap); 466 exit(1); 467 /*NOTREACHED*/ 468 } 469 470 static void 471 usage() 472 { 473 fprintf(stderr, 474 "usage: %s [ -fsoptions ] special-device%s\n", 475 progname, 476 #ifdef COMPAT 477 " [device-type]"); 478 #else 479 ""); 480 #endif 481 fprintf(stderr, "where fsoptions are:\n"); 482 fprintf(stderr, 483 "\t-N do not create file system, just print out parameters\n"); 484 fprintf(stderr, "\t-R regression test, supress random factors\n"); 485 fprintf(stderr, "\t-S sector size\n"); 486 #ifdef COMPAT 487 fprintf(stderr, "\t-T disktype\n"); 488 #endif 489 fprintf(stderr, "\t-U enable soft updates\n"); 490 fprintf(stderr, "\t-a maximum contiguous blocks\n"); 491 fprintf(stderr, "\t-b block size\n"); 492 fprintf(stderr, "\t-c cylinders/group\n"); 493 fprintf(stderr, "\t-e maximum blocks per file in a cylinder group\n"); 494 fprintf(stderr, "\t-f frag size\n"); 495 fprintf(stderr, "\t-g average file size\n"); 496 fprintf(stderr, "\t-h average files per directory\n"); 497 fprintf(stderr, "\t-i number of bytes per inode\n"); 498 fprintf(stderr, "\t-m minimum free space %%\n"); 499 fprintf(stderr, "\t-o optimization preference (`space' or `time')\n"); 500 fprintf(stderr, "\t-s file system size (sectors)\n"); 501 fprintf(stderr, "\t-u sectors/cylinder\n"); 502 fprintf(stderr, 503 "\t-v do not attempt to determine partition name from device name\n"); 504 exit(1); 505 } 506