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 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 27 /* All Rights Reserved */ 28 29 /* 30 * University Copyright- Copyright (c) 1982, 1986, 1988 31 * The Regents of the University of California 32 * All Rights Reserved 33 * 34 * University Acknowledgment- Portions of this document are derived from 35 * software developed by the University of California, Berkeley, and its 36 * contributors. 37 */ 38 39 #pragma ident "%Z%%M% %I% %E% SMI" 40 41 42 /* 43 * The maximum supported file system size (in sectors) is the 44 * number of frags that can be represented in an int32_t field 45 * (INT_MAX) times the maximum number of sectors per frag. Since 46 * the maximum frag size is MAXBSIZE, the maximum number of sectors 47 * per frag is MAXBSIZE/DEV_BSIZE. 48 */ 49 #define FS_MAX (((diskaddr_t)INT_MAX) * (MAXBSIZE/DEV_BSIZE)) 50 51 /* 52 * make file system for cylinder-group style file systems 53 * 54 * usage: 55 * 56 * mkfs [-F FSType] [-V] [-G [-P]] [-M dirname] [-m] [options] 57 * [-o specific_options] special size 58 * [nsect ntrack bsize fsize cpg minfree rps nbpi opt apc rotdelay 59 * 2 3 4 5 6 7 8 9 10 11 12 60 * nrpos maxcontig mtb] 61 * 13 14 15 62 * 63 * where specific_options are: 64 * N - no create 65 * nsect - The number of sectors per track 66 * ntrack - The number of tracks per cylinder 67 * bsize - block size 68 * fragsize - fragment size 69 * cgsize - The number of disk cylinders per cylinder group. 70 * free - minimum free space 71 * rps - rotational speed (rev/sec). 72 * nbpi - number of data bytes per allocated inode 73 * opt - optimization (space, time) 74 * apc - number of alternates 75 * gap - gap size 76 * nrpos - number of rotational positions 77 * maxcontig - maximum number of logical blocks that will be 78 * allocated contiguously before inserting rotational delay 79 * mtb - if "y", set up file system for eventual growth to over a 80 * a terabyte 81 * -P Do not grow the file system, but print on stdout the maximal 82 * size in sectors to which the file system can be increased. The calculated 83 * size is limited by the value provided by the operand size. 84 * 85 * Note that -P is a project-private interface and together with -G intended 86 * to be used only by the growfs script. It is therefore purposely not 87 * documented in the man page. 88 * The -P option is covered by PSARC case 2003/422. 89 */ 90 91 /* 92 * The following constants set the defaults used for the number 93 * of sectors/track (fs_nsect), and number of tracks/cyl (fs_ntrak). 94 * 95 * NSECT NTRAK 96 * 72MB CDC 18 9 97 * 30MB CDC 18 5 98 * 720KB Diskette 9 2 99 * 100 * However the defaults will be different for disks larger than CHSLIMIT. 101 */ 102 103 #define DFLNSECT 32 104 #define DFLNTRAK 16 105 106 /* 107 * The following default sectors and tracks values are used for 108 * non-efi disks that are larger than the CHS addressing limit. The 109 * existing default cpg of 16 (DESCPG) holds good for larger disks too. 110 */ 111 #define DEF_SECTORS_EFI 128 112 #define DEF_TRACKS_EFI 48 113 114 /* 115 * The maximum number of cylinders in a group depends upon how much 116 * information can be stored on a single cylinder. The default is to 117 * use 16 cylinders per group. This is effectively tradition - it was 118 * the largest value acceptable under SunOs 4.1 119 */ 120 #define DESCPG 16 /* desired fs_cpg */ 121 122 /* 123 * The following two constants set the default block and fragment sizes. 124 * Both constants must be a power of 2 and meet the following constraints: 125 * MINBSIZE <= DESBLKSIZE <= MAXBSIZE 126 * DEV_BSIZE <= DESFRAGSIZE <= DESBLKSIZE 127 * DESBLKSIZE / DESFRAGSIZE <= 8 128 */ 129 #define DESBLKSIZE 8192 130 #define DESFRAGSIZE 1024 131 132 /* 133 * MINFREE gives the minimum acceptable percentage of file system 134 * blocks which may be free. If the freelist drops below this level 135 * only the superuser may continue to allocate blocks. This may 136 * be set to 0 if no reserve of free blocks is deemed necessary, 137 * however throughput drops by fifty percent if the file system 138 * is run at between 90% and 100% full; thus the default value of 139 * fs_minfree is 10%. With 10% free space, fragmentation is not a 140 * problem, so we choose to optimize for time. 141 */ 142 #define MINFREE 10 143 #define DEFAULTOPT FS_OPTTIME 144 145 /* 146 * ROTDELAY gives the minimum number of milliseconds to initiate 147 * another disk transfer on the same cylinder. It is no longer used 148 * and will always default to 0. 149 */ 150 #define ROTDELAY 0 151 152 /* 153 * MAXBLKPG determines the maximum number of data blocks which are 154 * placed in a single cylinder group. The default is one indirect 155 * block worth of data blocks. 156 */ 157 #define MAXBLKPG(bsize) ((bsize) / sizeof (daddr32_t)) 158 159 /* 160 * Each file system has a number of inodes statically allocated. 161 * We allocate one inode slot per NBPI bytes, expecting this 162 * to be far more than we will ever need. 163 */ 164 #define NBPI 2048 /* Number Bytes Per Inode */ 165 #define MTB_NBPI (MB) /* Number Bytes Per Inode for multi-terabyte */ 166 167 /* 168 * Disks are assumed to rotate at 60HZ, unless otherwise specified. 169 */ 170 #define DEFHZ 60 171 172 /* 173 * Cylinder group related limits. 174 * 175 * For each cylinder we keep track of the availability of blocks at different 176 * rotational positions, so that we can lay out the data to be picked 177 * up with minimum rotational latency. NRPOS is the number of rotational 178 * positions which we distinguish. With NRPOS 8 the resolution of our 179 * summary information is 2ms for a typical 3600 rpm drive. 180 */ 181 #define NRPOS 8 /* number distinct rotational positions */ 182 183 #ifdef DEBUG 184 #define dprintf(x) printf x 185 #else 186 #define dprintf(x) 187 #endif 188 189 /* 190 * For the -N option, when calculating the backup superblocks, do not print 191 * them if we are not really sure. We may have to try an alternate method of 192 * arriving at the superblocks. So defer printing till a handful of superblocks 193 * look good. 194 */ 195 #define tprintf(x) if (Nflag && retry) \ 196 (void) strncat(tmpbuf, x, strlen(x)); \ 197 else \ 198 (void) fprintf(stderr, x); 199 200 #define ALTSB 32 /* Location of first backup superblock */ 201 202 /* 203 * range_check "user_supplied" flag values. 204 */ 205 #define RC_DEFAULT 0 206 #define RC_KEYWORD 1 207 #define RC_POSITIONAL 2 208 209 /* 210 * ufs hole 211 */ 212 #define UFS_HOLE -1 213 214 #ifndef STANDALONE 215 #include <stdio.h> 216 #include <sys/mnttab.h> 217 #endif 218 219 #include <stdlib.h> 220 #include <unistd.h> 221 #include <malloc.h> 222 #include <string.h> 223 #include <strings.h> 224 #include <ctype.h> 225 #include <errno.h> 226 #include <sys/param.h> 227 #include <time.h> 228 #include <sys/types.h> 229 #include <sys/sysmacros.h> 230 #include <sys/vnode.h> 231 #include <sys/fs/ufs_fsdir.h> 232 #include <sys/fs/ufs_inode.h> 233 #include <sys/fs/ufs_fs.h> 234 #include <sys/fs/ufs_log.h> 235 #include <sys/mntent.h> 236 #include <sys/filio.h> 237 #include <limits.h> 238 #include <sys/int_const.h> 239 #include <signal.h> 240 #include <sys/efi_partition.h> 241 #include "roll_log.h" 242 243 #define bcopy(f, t, n) (void) memcpy(t, f, n) 244 #define bzero(s, n) (void) memset(s, 0, n) 245 #define bcmp(s, d, n) memcmp(s, d, n) 246 247 #define index(s, r) strchr(s, r) 248 #define rindex(s, r) strrchr(s, r) 249 250 #include <sys/stat.h> 251 #include <sys/statvfs.h> 252 #include <locale.h> 253 #include <fcntl.h> 254 #include <sys/isa_defs.h> /* for ENDIAN defines */ 255 #include <sys/vtoc.h> 256 257 #include <sys/dkio.h> 258 #include <sys/asynch.h> 259 260 extern offset_t llseek(); 261 extern char *getfullblkname(); 262 extern long lrand48(); 263 264 extern int optind; 265 extern char *optarg; 266 267 268 /* 269 * The size of a cylinder group is calculated by CGSIZE. The maximum size 270 * is limited by the fact that cylinder groups are at most one block. 271 * Its size is derived from the size of the maps maintained in the 272 * cylinder group and the (struct cg) size. 273 */ 274 #define CGSIZE(fs) \ 275 /* base cg */ (sizeof (struct cg) + \ 276 /* blktot size */ (fs)->fs_cpg * sizeof (long) + \ 277 /* blks size */ (fs)->fs_cpg * (fs)->fs_nrpos * sizeof (short) + \ 278 /* inode map */ howmany((fs)->fs_ipg, NBBY) + \ 279 /* block map */ howmany((fs)->fs_cpg * (fs)->fs_spc / NSPF(fs), NBBY)) 280 281 /* 282 * We limit the size of the inode map to be no more than a 283 * third of the cylinder group space, since we must leave at 284 * least an equal amount of space for the block map. 285 * 286 * N.B.: MAXIpG must be a multiple of INOPB(fs). 287 */ 288 #define MAXIpG(fs) roundup((fs)->fs_bsize * NBBY / 3, INOPB(fs)) 289 290 /* 291 * Same as MAXIpG, but parameterized by the block size (b) and the 292 * cylinder group divisor (d), which is the reciprocal of the fraction of the 293 * cylinder group overhead block that is used for the inode map. So for 294 * example, if d = 5, the macro's computation assumes that 1/5 of the 295 * cylinder group overhead block can be dedicated to the inode map. 296 */ 297 #define MAXIpG_B(b, d) roundup((b) * NBBY / (d), (b) / sizeof (struct dinode)) 298 299 #define UMASK 0755 300 #define MAXINOPB (MAXBSIZE / sizeof (struct dinode)) 301 #define POWEROF2(num) (((num) & ((num) - 1)) == 0) 302 #define MB (1024*1024) 303 #define BETWEEN(x, l, h) ((x) >= (l) && (x) <= (h)) 304 305 /* 306 * Used to set the inode generation number. Since both inodes and dinodes 307 * are dealt with, we really need a pointer to an icommon here. 308 */ 309 #define IRANDOMIZE(icp) (icp)->ic_gen = lrand48(); 310 311 /* 312 * Flags for number() 313 */ 314 #define ALLOW_PERCENT 0x01 /* allow trailing `%' on number */ 315 #define ALLOW_MS1 0x02 /* allow trailing `ms', state 1 */ 316 #define ALLOW_MS2 0x04 /* allow trailing `ms', state 2 */ 317 #define ALLOW_END_ONLY 0x08 /* must be at end of number & suffixes */ 318 319 #define MAXAIO 1000 /* maximum number of outstanding I/O's we'll manage */ 320 #define BLOCK 1 /* block in aiowait */ 321 #define NOBLOCK 0 /* don't block in aiowait */ 322 323 #define RELEASE 1 /* free an aio buffer after use */ 324 #define SAVE 0 /* don't free the buffer */ 325 326 typedef struct aio_trans { 327 aio_result_t resultbuf; 328 diskaddr_t bno; 329 char *buffer; 330 int size; 331 int release; 332 struct aio_trans *next; 333 } aio_trans; 334 335 typedef struct aio_results { 336 int max; 337 int outstanding; 338 int maxpend; 339 aio_trans *trans; 340 } aio_results; 341 342 int aio_inited = 0; 343 aio_results results; 344 345 /* 346 * Allow up to MAXBUF aio requests that each have a unique buffer. 347 * More aio's might be done, but not using memory through the getbuf() 348 * interface. This can be raised, but you run into the potential of 349 * using more memory than is physically available on the machine, 350 * and if you start swapping, you can forget about performance. 351 * To prevent this, we also limit the total memory used for a given 352 * type of buffer to MAXBUFMEM. 353 * 354 * Tests indicate a cylinder group's worth of inodes takes: 355 * 356 * NBPI Size of Inode Buffer 357 * 2k 1688k 358 * 8k 424k 359 * 360 * initcg() stores all the inodes for a cylinder group in one buffer, 361 * so allowing 20 buffers could take 32 MB if not limited by MAXBUFMEM. 362 */ 363 #define MAXBUF 20 364 #define MAXBUFMEM (8 * 1024 * 1024) 365 366 /* 367 * header information for buffers managed by getbuf() and freebuf() 368 */ 369 typedef struct bufhdr { 370 struct bufhdr *head; 371 struct bufhdr *next; 372 } bufhdr; 373 374 int bufhdrsize; 375 376 bufhdr inodebuf = { NULL, NULL }; 377 bufhdr cgsumbuf = { NULL, NULL }; 378 379 #define SECTORS_PER_TERABYTE (1LL << 31) 380 /* 381 * The following constant specifies an upper limit for file system size 382 * that is actually a lot bigger than we expect to support with UFS. (Since 383 * it's specified in sectors, the file system size would be 2**44 * 512, 384 * which is 2**53, which is 8192 Terabytes.) However, it's useful 385 * for checking the basic sanity of a size value that is input on the 386 * command line. 387 */ 388 #define FS_SIZE_UPPER_LIMIT 0x100000000000LL 389 390 /* 391 * Forward declarations 392 */ 393 static char *getbuf(bufhdr *bufhead, int size); 394 static void freebuf(char *buf); 395 static void freetrans(aio_trans *transp); 396 static aio_trans *get_aiop(); 397 static aio_trans *wait_for_write(int block); 398 static void initcg(int cylno); 399 static void fsinit(); 400 static int makedir(struct direct *protodir, int entries); 401 static void iput(struct inode *ip); 402 static void rdfs(diskaddr_t bno, int size, char *bf); 403 static void wtfs(diskaddr_t bno, int size, char *bf); 404 static void awtfs(diskaddr_t bno, int size, char *bf, int release); 405 static void wtfs_breakup(diskaddr_t bno, int size, char *bf); 406 static int isblock(struct fs *fs, unsigned char *cp, int h); 407 static void clrblock(struct fs *fs, unsigned char *cp, int h); 408 static void setblock(struct fs *fs, unsigned char *cp, int h); 409 static void usage(); 410 static void dump_fscmd(char *fsys, int fsi); 411 static uint64_t number(uint64_t d_value, char *param, int flags); 412 static int match(char *s); 413 static char checkopt(char *optim); 414 static char checkmtb(char *mtbarg); 415 static void range_check(long *varp, char *name, long minimum, 416 long maximum, long def_val, int user_supplied); 417 static void range_check_64(uint64_t *varp, char *name, uint64_t minimum, 418 uint64_t maximum, uint64_t def_val, int user_supplied); 419 static daddr32_t alloc(int size, int mode); 420 static diskaddr_t get_max_size(int fd); 421 static long get_max_track_size(int fd); 422 static void block_sigint(sigset_t *old_mask); 423 static void unblock_sigint(sigset_t *old_mask); 424 static void recover_from_sigint(int signum); 425 static int confirm_abort(void); 426 static int getline(FILE *fp, char *loc, int maxlen); 427 static void flush_writes(void); 428 static long compute_maxcpg(long, long, long, long, long); 429 static int in_64bit_mode(void); 430 static int validate_size(int fd, diskaddr_t size); 431 static void dump_sblock(void); 432 433 union { 434 struct fs fs; 435 char pad[SBSIZE]; 436 } fsun, altfsun; 437 #define sblock fsun.fs 438 #define altsblock altfsun.fs 439 440 struct csum *fscs; 441 442 union cgun { 443 struct cg cg; 444 char pad[MAXBSIZE]; 445 } cgun; 446 447 #define acg cgun.cg 448 /* 449 * Size of screen in cols in which to fit output 450 */ 451 #define WIDTH 80 452 453 struct dinode zino[MAXBSIZE / sizeof (struct dinode)]; 454 455 /* 456 * file descriptors used for rdfs(fsi) and wtfs(fso). 457 * Initialized to an illegal file descriptor number. 458 */ 459 int fsi = -1; 460 int fso = -1; 461 462 /* 463 * The BIG parameter is machine dependent. It should be a longlong integer 464 * constant that can be used by the number parser to check the validity 465 * of numeric parameters. 466 */ 467 468 #define BIG 0x7fffffffffffffffLL 469 470 /* Used to indicate to number() that a bogus value should cause us to exit */ 471 #define NO_DEFAULT LONG_MIN 472 473 /* 474 * INVALIDSBLIMIT is the number of bad backup superblocks that will be 475 * tolerated before we decide to try arriving at a different set of them 476 * using a different logic. This is applicable for non-EFI disks only. 477 */ 478 #define INVALIDSBLIMIT 10 479 480 /* 481 * The *_flag variables are used to indicate that the user specified 482 * the values, rather than that we made them up ourselves. We can 483 * complain about the user giving us bogus values. 484 */ 485 486 /* semi-constants */ 487 long sectorsize = DEV_BSIZE; /* bytes/sector from param.h */ 488 long bbsize = BBSIZE; /* boot block size */ 489 long sbsize = SBSIZE; /* superblock size */ 490 491 /* parameters */ 492 diskaddr_t fssize_db; /* file system size in disk blocks */ 493 diskaddr_t fssize_frag; /* file system size in frags */ 494 long cpg; /* cylinders/cylinder group */ 495 int cpg_flag = RC_DEFAULT; 496 long rotdelay = -1; /* rotational delay between blocks */ 497 int rotdelay_flag = RC_DEFAULT; 498 long maxcontig; /* max contiguous blocks to allocate */ 499 int maxcontig_flag = RC_DEFAULT; 500 long nsect = DFLNSECT; /* sectors per track */ 501 int nsect_flag = RC_DEFAULT; 502 long ntrack = DFLNTRAK; /* tracks per cylinder group */ 503 int ntrack_flag = RC_DEFAULT; 504 long bsize = DESBLKSIZE; /* filesystem block size */ 505 int bsize_flag = RC_DEFAULT; 506 long fragsize = DESFRAGSIZE; /* filesystem fragment size */ 507 int fragsize_flag = RC_DEFAULT; 508 long minfree = MINFREE; /* fs_minfree */ 509 int minfree_flag = RC_DEFAULT; 510 long rps = DEFHZ; /* revolutions/second of drive */ 511 int rps_flag = RC_DEFAULT; 512 long nbpi = NBPI; /* number of bytes per inode */ 513 int nbpi_flag = RC_DEFAULT; 514 long nrpos = NRPOS; /* number of rotational positions */ 515 int nrpos_flag = RC_DEFAULT; 516 long apc = 0; /* alternate sectors per cylinder */ 517 int apc_flag = RC_DEFAULT; 518 char opt = 't'; /* optimization style, `t' or `s' */ 519 char mtb = 'n'; /* multi-terabyte format, 'y' or 'n' */ 520 521 long debug = 0; /* enable debugging output */ 522 523 int spc_flag = 0; /* alternate sectors specified or */ 524 /* found */ 525 526 /* global state */ 527 int Nflag; /* do not write to disk */ 528 int mflag; /* return the command line used to create this FS */ 529 int rflag; /* report the superblock in an easily-parsed form */ 530 int Rflag; /* dump the superblock in binary */ 531 char *fsys; 532 time_t mkfstime; 533 char *string; 534 int label_type; 535 536 /* 537 * logging support 538 */ 539 int ismdd; /* true if device is a SVM device */ 540 int islog; /* true if ufs or SVM logging is enabled */ 541 int islogok; /* true if ufs/SVM log state is good */ 542 543 static int isufslog; /* true if ufs logging is enabled */ 544 static int waslog; /* true when ufs logging disabled during grow */ 545 546 /* 547 * growfs defines, globals, and forward references 548 */ 549 #define NOTENOUGHSPACE 33 550 int grow; 551 static int Pflag; /* probe to which size the fs can be grown */ 552 int ismounted; 553 char *directory; 554 diskaddr_t grow_fssize; 555 long grow_fs_size; 556 long grow_fs_ncg; 557 diskaddr_t grow_fs_csaddr; 558 long grow_fs_cssize; 559 int grow_fs_clean; 560 struct csum *grow_fscs; 561 diskaddr_t grow_sifrag; 562 int test; 563 int testforce; 564 diskaddr_t testfrags; 565 int inlockexit; 566 int isbad; 567 568 void lockexit(int); 569 void randomgeneration(void); 570 void checksummarysize(void); 571 int checksblock(struct fs, int); 572 void growinit(char *); 573 void checkdev(char *, char *); 574 void checkmount(struct mnttab *, char *); 575 struct dinode *gdinode(ino_t); 576 int csfraginrange(daddr32_t); 577 struct csfrag *findcsfrag(daddr32_t, struct csfrag **); 578 void checkindirect(ino_t, daddr32_t *, daddr32_t, int); 579 void addcsfrag(ino_t, daddr32_t, struct csfrag **); 580 void delcsfrag(daddr32_t, struct csfrag **); 581 void checkdirect(ino_t, daddr32_t *, daddr32_t *, int); 582 void findcsfragino(void); 583 void fixindirect(daddr32_t, int); 584 void fixdirect(caddr_t, daddr32_t, daddr32_t *, int); 585 void fixcsfragino(void); 586 void extendsummaryinfo(void); 587 int notenoughspace(void); 588 void unalloccsfragino(void); 589 void unalloccsfragfree(void); 590 void findcsfragfree(void); 591 void copycsfragino(void); 592 void rdcg(long); 593 void wtcg(void); 594 void flcg(void); 595 void allocfrags(long, daddr32_t *, long *); 596 void alloccsfragino(void); 597 void alloccsfragfree(void); 598 void freefrags(daddr32_t, long, long); 599 int findfreerange(long *, long *); 600 void resetallocinfo(void); 601 void extendcg(long); 602 void ulockfs(void); 603 void wlockfs(void); 604 void clockfs(void); 605 void wtsb(void); 606 static int64_t checkfragallocated(daddr32_t); 607 static struct csum *read_summaryinfo(struct fs *); 608 static diskaddr_t probe_summaryinfo(); 609 610 int 611 main(int argc, char *argv[]) 612 { 613 long i, mincpc, mincpg, ibpcl; 614 long cylno, rpos, blk, j, warn = 0; 615 long mincpgcnt, maxcpg; 616 uint64_t used, bpcg, inospercg; 617 long mapcramped, inodecramped; 618 long postblsize, rotblsize, totalsbsize; 619 FILE *mnttab; 620 struct mnttab mntp; 621 char *special; 622 struct statvfs64 fs; 623 struct dk_geom dkg; 624 struct dk_cinfo dkcinfo; 625 char pbuf[sizeof (uint64_t) * 3 + 1]; 626 char *tmpbuf; 627 int width, plen; 628 uint64_t num; 629 int c, saverr; 630 diskaddr_t max_fssize; 631 long tmpmaxcontig = -1; 632 struct sigaction sigact; 633 uint64_t nbytes64; 634 int remaining_cg; 635 int do_dot = 0; 636 int use_efi_dflts = 0, retry = 0; 637 int invalid_sb_cnt, ret, skip_this_sb, cg_too_small; 638 int geom_nsect, geom_ntrack, geom_cpg; 639 640 (void) setlocale(LC_ALL, ""); 641 642 #if !defined(TEXT_DOMAIN) 643 #define TEXT_DOMAIN "SYS_TEST" 644 #endif 645 (void) textdomain(TEXT_DOMAIN); 646 647 while ((c = getopt(argc, argv, "F:bmo:VPGM:T:t:")) != EOF) { 648 switch (c) { 649 650 case 'F': 651 string = optarg; 652 if (strcmp(string, "ufs") != 0) 653 usage(); 654 break; 655 656 case 'm': /* return command line used to create this FS */ 657 mflag++; 658 break; 659 660 case 'o': 661 /* 662 * ufs specific options. 663 */ 664 string = optarg; 665 while (*string != '\0') { 666 if (match("nsect=")) { 667 nsect = number(DFLNSECT, "nsect", 0); 668 nsect_flag = RC_KEYWORD; 669 } else if (match("ntrack=")) { 670 ntrack = number(DFLNTRAK, "ntrack", 0); 671 ntrack_flag = RC_KEYWORD; 672 } else if (match("bsize=")) { 673 bsize = number(DESBLKSIZE, "bsize", 0); 674 bsize_flag = RC_KEYWORD; 675 } else if (match("fragsize=")) { 676 fragsize = number(DESFRAGSIZE, 677 "fragsize", 0); 678 fragsize_flag = RC_KEYWORD; 679 } else if (match("cgsize=")) { 680 cpg = number(DESCPG, "cgsize", 0); 681 cpg_flag = RC_KEYWORD; 682 } else if (match("free=")) { 683 minfree = number(MINFREE, "free", 684 ALLOW_PERCENT); 685 minfree_flag = RC_KEYWORD; 686 } else if (match("maxcontig=")) { 687 tmpmaxcontig = 688 number(-1, "maxcontig", 0); 689 maxcontig_flag = RC_KEYWORD; 690 } else if (match("nrpos=")) { 691 nrpos = number(NRPOS, "nrpos", 0); 692 nrpos_flag = RC_KEYWORD; 693 } else if (match("rps=")) { 694 rps = number(DEFHZ, "rps", 0); 695 rps_flag = RC_KEYWORD; 696 } else if (match("nbpi=")) { 697 nbpi = number(NBPI, "nbpi", 0); 698 nbpi_flag = RC_KEYWORD; 699 } else if (match("opt=")) { 700 opt = checkopt(string); 701 } else if (match("mtb=")) { 702 mtb = checkmtb(string); 703 } else if (match("apc=")) { 704 apc = number(0, "apc", 0); 705 apc_flag = RC_KEYWORD; 706 } else if (match("gap=")) { 707 (void) number(0, "gap", ALLOW_MS1); 708 rotdelay = ROTDELAY; 709 rotdelay_flag = RC_DEFAULT; 710 } else if (match("debug=")) { 711 debug = number(0, "debug", 0); 712 } else if (match("N")) { 713 Nflag++; 714 } else if (match("calcsb")) { 715 rflag++; 716 Nflag++; 717 } else if (match("calcbinsb")) { 718 rflag++; 719 Rflag++; 720 Nflag++; 721 } else if (*string == '\0') { 722 break; 723 } else { 724 (void) fprintf(stderr, gettext( 725 "illegal option: %s\n"), 726 string); 727 usage(); 728 } 729 730 if (*string == ',') string++; 731 if (*string == ' ') string++; 732 } 733 break; 734 735 case 'V': 736 { 737 char *opt_text; 738 int opt_count; 739 740 (void) fprintf(stdout, gettext("mkfs -F ufs ")); 741 for (opt_count = 1; opt_count < argc; 742 opt_count++) { 743 opt_text = argv[opt_count]; 744 if (opt_text) 745 (void) fprintf(stdout, " %s ", 746 opt_text); 747 } 748 (void) fprintf(stdout, "\n"); 749 } 750 break; 751 752 case 'b': /* do nothing for this */ 753 break; 754 755 case 'M': /* grow the mounted file system */ 756 directory = optarg; 757 758 /* FALLTHROUGH */ 759 case 'G': /* grow the file system */ 760 grow = 1; 761 break; 762 case 'P': /* probe the file system growing size */ 763 Pflag = 1; 764 grow = 1; /* probe mode implies fs growing */ 765 break; 766 case 'T': /* For testing */ 767 testforce = 1; 768 769 /* FALLTHROUGH */ 770 case 't': 771 test = 1; 772 string = optarg; 773 testfrags = number(NO_DEFAULT, "testfrags", 0); 774 break; 775 776 case '?': 777 usage(); 778 break; 779 } 780 } 781 #ifdef MKFS_DEBUG 782 /* 783 * Turning on MKFS_DEBUG causes mkfs to produce a filesystem 784 * that can be reproduced by setting the time to 0 and seeding 785 * the random number generator to a constant. 786 */ 787 mkfstime = 0; /* reproducible results */ 788 #else 789 (void) time(&mkfstime); 790 #endif 791 792 if (optind >= (argc - 1)) { 793 if (optind > (argc - 1)) { 794 (void) fprintf(stderr, 795 gettext("special not specified\n")); 796 usage(); 797 } else if (mflag == 0) { 798 (void) fprintf(stderr, 799 gettext("size not specified\n")); 800 usage(); 801 } 802 } 803 argc -= optind; 804 argv = &argv[optind]; 805 806 fsys = argv[0]; 807 fsi = open64(fsys, O_RDONLY); 808 if (fsi < 0) { 809 (void) fprintf(stderr, gettext("%s: cannot open\n"), fsys); 810 lockexit(32); 811 } 812 813 if (mflag) { 814 dump_fscmd(fsys, fsi); 815 lockexit(0); 816 } 817 818 /* 819 * The task of setting all of the configuration parameters for a 820 * UFS file system is basically a matter of solving n equations 821 * in m variables. Typically, m is greater than n, so there is 822 * usually more than one valid solution. Since this is usually 823 * an under-constrained problem, it's not always obvious what the 824 * "best" configuration is. 825 * 826 * In general, the approach is to 827 * 1. Determine the values for the file system parameters 828 * that are externally contrained and therefore not adjustable 829 * by mkfs (such as the device's size and maxtransfer size). 830 * 2. Acquire the user's requested setting for all configuration 831 * values that can be set on the command line. 832 * 3. Determine the final value of all configuration values, by 833 * the following approach: 834 * - set the file system block size (fs_bsize). Although 835 * this could be regarded as an adjustable parameter, in 836 * fact, it's pretty much a constant. At this time, it's 837 * generally set to 8k (with older hardware, it can 838 * sometimes make sense to set it to 4k, but those 839 * situations are pretty rare now). 840 * - re-adjust the maximum file system size based on the 841 * value of the file system block size. Since the 842 * frag size can't be any larger than a file system 843 * block, and the number of frags in the file system 844 * has to fit into 31 bits, the file system block size 845 * affects the maximum file system size. 846 * - now that the real maximum file system is known, set the 847 * actual size of the file system to be created to 848 * MIN(requested size, maximum file system size). 849 * - now validate, and if necessary, adjust the following 850 * values: 851 * rotdelay 852 * nsect 853 * maxcontig 854 * apc 855 * frag_size 856 * rps 857 * minfree 858 * nrpos 859 * nrack 860 * nbpi 861 * - calculate maxcpg (the maximum value of the cylinders-per- 862 * cylinder-group configuration parameters). There are two 863 * algorithms for calculating maxcpg: an old one, which is 864 * used for file systems of less than 1 terabyte, and a 865 * new one, implemented in the function compute_maxcpg(), 866 * which is used for file systems of greater than 1 TB. 867 * The difference between them is that compute_maxcpg() 868 * really tries to maximize the cpg value. The old 869 * algorithm fails to take advantage of smaller frags and 870 * lower inode density when determining the maximum cpg, 871 * and thus comes up with much lower numbers in some 872 * configurations. At some point, we might use the 873 * new algorithm for determining maxcpg for all file 874 * systems, but at this time, the changes implemented for 875 * multi-terabyte UFS are NOT being automatically applied 876 * to UFS file systems of less than a terabyte (in the 877 * interest of not changing existing UFS policy too much 878 * until the ramifications of the changes are well-understood 879 * and have been evaluated for their effects on performance.) 880 * - check the current values of the configuration parameters 881 * against the various constraints imposed by UFS. These 882 * include: 883 * * There must be at least one inode in each 884 * cylinder group. 885 * * The cylinder group overhead block, which 886 * contains the inode and frag bigmaps, must fit 887 * within one file system block. 888 * * The space required for inode maps should 889 * occupy no more than a third of the cylinder 890 * group overhead block. 891 * * The rotational position tables have to fit 892 * within the available space in the super block. 893 * Adjust the configuration values that can be adjusted 894 * so that these constraints are satisfied. The 895 * configuration values that are adjustable are: 896 * * frag size 897 * * cylinders per group 898 * * inode density (can be increased) 899 * * number of rotational positions (the rotational 900 * position tables are eliminated altogether if 901 * there isn't enough room for them.) 902 * 4. Set the values for all the dependent configuration 903 * values (those that aren't settable on the command 904 * line and which are completely dependent on the 905 * adjustable parameters). This include cpc (cycles 906 * per cylinder, spc (sectors-per-cylinder), and many others. 907 */ 908 909 max_fssize = get_max_size(fsi); 910 911 /* 912 * Get and check positional arguments, if any. 913 */ 914 switch (argc - 1) { 915 default: 916 usage(); 917 /*NOTREACHED*/ 918 case 15: 919 mtb = checkmtb(argv[15]); 920 /* FALLTHROUGH */ 921 case 14: 922 string = argv[14]; 923 tmpmaxcontig = number(-1, "maxcontig", 0); 924 maxcontig_flag = RC_POSITIONAL; 925 /* FALLTHROUGH */ 926 case 13: 927 string = argv[13]; 928 nrpos = number(NRPOS, "nrpos", 0); 929 nrpos_flag = RC_POSITIONAL; 930 /* FALLTHROUGH */ 931 case 12: 932 string = argv[12]; 933 rotdelay = ROTDELAY; 934 rotdelay_flag = RC_DEFAULT; 935 /* FALLTHROUGH */ 936 case 11: 937 string = argv[11]; 938 apc = number(0, "apc", 0); 939 apc_flag = RC_POSITIONAL; 940 /* FALLTHROUGH */ 941 case 10: 942 opt = checkopt(argv[10]); 943 /* FALLTHROUGH */ 944 case 9: 945 string = argv[9]; 946 nbpi = number(NBPI, "nbpi", 0); 947 nbpi_flag = RC_POSITIONAL; 948 /* FALLTHROUGH */ 949 case 8: 950 string = argv[8]; 951 rps = number(DEFHZ, "rps", 0); 952 rps_flag = RC_POSITIONAL; 953 /* FALLTHROUGH */ 954 case 7: 955 string = argv[7]; 956 minfree = number(MINFREE, "free", ALLOW_PERCENT); 957 minfree_flag = RC_POSITIONAL; 958 /* FALLTHROUGH */ 959 case 6: 960 string = argv[6]; 961 cpg = number(DESCPG, "cgsize", 0); 962 cpg_flag = RC_POSITIONAL; 963 /* FALLTHROUGH */ 964 case 5: 965 string = argv[5]; 966 fragsize = number(DESFRAGSIZE, "fragsize", 0); 967 fragsize_flag = RC_POSITIONAL; 968 /* FALLTHROUGH */ 969 case 4: 970 string = argv[4]; 971 bsize = number(DESBLKSIZE, "bsize", 0); 972 bsize_flag = RC_POSITIONAL; 973 /* FALLTHROUGH */ 974 case 3: 975 string = argv[3]; 976 ntrack = number(DFLNTRAK, "ntrack", 0); 977 ntrack_flag = RC_POSITIONAL; 978 /* FALLTHROUGH */ 979 case 2: 980 string = argv[2]; 981 nsect = number(DFLNSECT, "nsect", 0); 982 nsect_flag = RC_POSITIONAL; 983 /* FALLTHROUGH */ 984 case 1: 985 string = argv[1]; 986 fssize_db = number(max_fssize, "size", 0); 987 } 988 989 990 if ((maxcontig_flag == RC_DEFAULT) || (tmpmaxcontig == -1) || 991 (maxcontig == -1)) { 992 long maxtrax = get_max_track_size(fsi); 993 maxcontig = maxtrax / bsize; 994 995 } else { 996 maxcontig = tmpmaxcontig; 997 } 998 dprintf(("DeBuG maxcontig : %ld\n", maxcontig)); 999 1000 if (rotdelay == -1) { /* default by newfs and mkfs */ 1001 rotdelay = ROTDELAY; 1002 } 1003 1004 if (cpg_flag == RC_DEFAULT) { /* If not explicity set, use default */ 1005 cpg = DESCPG; 1006 } 1007 dprintf(("DeBuG cpg : %ld\n", cpg)); 1008 1009 /* 1010 * Now that we have the semi-sane args, either positional, via -o, 1011 * or by defaulting, handle inter-dependencies and range checks. 1012 */ 1013 1014 /* 1015 * Settle the file system block size first, since it's a fixed 1016 * parameter once set and so many other parameters, including 1017 * max_fssize, depend on it. 1018 */ 1019 range_check(&bsize, "bsize", MINBSIZE, MAXBSIZE, DESBLKSIZE, 1020 bsize_flag); 1021 1022 if (!POWEROF2(bsize)) { 1023 (void) fprintf(stderr, 1024 gettext("block size must be a power of 2, not %ld\n"), 1025 bsize); 1026 bsize = DESBLKSIZE; 1027 (void) fprintf(stderr, 1028 gettext("mkfs: bsize reset to default %ld\n"), 1029 bsize); 1030 } 1031 1032 if (fssize_db > max_fssize && validate_size(fsi, fssize_db)) { 1033 (void) fprintf(stderr, gettext( 1034 "Warning: the requested size of this file system\n" 1035 "(%lld sectors) is greater than the size of the\n" 1036 "device reported by the driver (%lld sectors).\n" 1037 "However, a read of the device at the requested size\n" 1038 "does succeed, so the requested size will be used.\n"), 1039 fssize_db, max_fssize); 1040 max_fssize = fssize_db; 1041 } 1042 /* 1043 * Since the maximum allocatable unit (the frag) must be less than 1044 * or equal to bsize, and the number of frags must be less than or 1045 * equal to INT_MAX, the total size of the file system (in 1046 * bytes) must be less than or equal to bsize * INT_MAX. 1047 */ 1048 1049 if (max_fssize > ((diskaddr_t)bsize/DEV_BSIZE) * INT_MAX) 1050 max_fssize = ((diskaddr_t)bsize/DEV_BSIZE) * INT_MAX; 1051 range_check_64(&fssize_db, "size", 1024LL, max_fssize, max_fssize, 1); 1052 1053 if (fssize_db >= SECTORS_PER_TERABYTE) { 1054 mtb = 'y'; 1055 if (!in_64bit_mode()) { 1056 (void) fprintf(stderr, gettext( 1057 "mkfs: Warning: Creating a file system greater than 1 terabyte on a\n" 1058 " system running a 32-bit kernel. This file system will not be\n" 1059 " accessible until the system is rebooted with a 64-bit kernel.\n")); 1060 } 1061 } 1062 1063 /* 1064 * With newer and much larger disks, the newfs(1M) and mkfs_ufs(1M) 1065 * commands had problems in correctly handling the "native" geometries 1066 * for various storage devices. 1067 * 1068 * To handle the new age disks, mkfs_ufs(1M) will use the EFI style 1069 * for non-EFI disks that are larger than the CHS addressing limit 1070 * ( > 8GB approx ) and ignore the disk geometry information for 1071 * these drives. This is what is currently done for multi-terrabyte 1072 * filesystems on EFI disks. 1073 * 1074 * However if the user asked for a specific layout by supplying values 1075 * for even one of the three parameters (nsect, ntrack, cpg), honour 1076 * the user supplied parameters. 1077 * 1078 * Choosing EFI style or native geometry style can make a lot of 1079 * difference, because the size of a cylinder group is dependent on 1080 * this choice. This in turn means that the position of alternate 1081 * superblocks varies depending on the style chosen. It is not 1082 * necessary that all disks of size > CHSLIMIT have EFI style layout. 1083 * There can be disks which are > CHSLIMIT size, but have native 1084 * geometry style layout, thereby warranting the need for alternate 1085 * logic in superblock detection. 1086 */ 1087 1088 if (mtb != 'y' && label_type == LABEL_TYPE_VTOC && 1089 ((ntrack == -1 || (grow && ntrack_flag == RC_DEFAULT)) || 1090 (nsect_flag == RC_DEFAULT && ntrack_flag == RC_DEFAULT && 1091 cpg_flag == RC_DEFAULT))) { 1092 /* 1093 * "-1" indicates that we were called from newfs and ntracks 1094 * was not specified in newfs command line. Calculate nsect 1095 * and ntrack in the same manner as newfs. 1096 * 1097 * This is required because, the defaults for nsect and ntrack 1098 * is hardcoded in mkfs, whereas to generate the alternate 1099 * superblock locations for the -N option, there is a need for 1100 * the geometry based values that newfs would have arrived at. 1101 * Newfs would have arrived at these values as below. 1102 */ 1103 1104 if (ioctl(fsi, DKIOCGGEOM, &dkg)) { 1105 dprintf(("%s: Unable to read Disk geometry", fsys)); 1106 perror(gettext("Unable to read Disk geometry")); 1107 lockexit(32); 1108 } else { 1109 nsect = dkg.dkg_nsect; 1110 ntrack = dkg.dkg_nhead; 1111 #ifdef i386 /* Bug 1170182 */ 1112 if (ntrack > 32 && (ntrack % 16) != 0) { 1113 ntrack -= (ntrack % 16); 1114 } 1115 #endif 1116 if ((dkg.dkg_ncyl * dkg.dkg_nhead * dkg.dkg_nsect) 1117 > CHSLIMIT) { 1118 use_efi_dflts = 1; 1119 retry = 1; 1120 } 1121 } 1122 dprintf(("DeBuG CHSLIMIT = %d geom = %ld\n", CHSLIMIT, 1123 dkg.dkg_ncyl * dkg.dkg_nhead * dkg.dkg_nsect)); 1124 } 1125 1126 /* 1127 * For the newfs -N case, even if the disksize is > CHSLIMIT, do not 1128 * blindly follow EFI style. If the fs_version indicates a geometry 1129 * based layout, try that one first. If it fails we can always try the 1130 * other logic. 1131 * 1132 * If we were called from growfs, we will have a problem if we mix 1133 * and match the filesystem creation and growth styles. For example, 1134 * if we create using EFI style, we have to also grow using EFI 1135 * style. So follow the style indicated by the fs_version. 1136 * 1137 * Read and verify the primary superblock. If it looks sane, use the 1138 * fs_version from the superblock. If the primary superblock does 1139 * not look good, read and verify the first alternate superblock at 1140 * ALTSB. Use the fs_version to decide whether to use the 1141 * EFI style logic or the old geometry based logic to calculate 1142 * the alternate superblock locations. 1143 */ 1144 if ((Nflag && use_efi_dflts) || (grow)) { 1145 if (grow && ntrack_flag != RC_DEFAULT) 1146 goto start_fs_creation; 1147 rdfs((diskaddr_t)(SBOFF / sectorsize), (int)sbsize, 1148 (char *)&altsblock); 1149 ret = checksblock(altsblock, 1); 1150 1151 if (!ret) { 1152 if (altsblock.fs_magic == MTB_UFS_MAGIC) { 1153 mtb = 'y'; 1154 goto start_fs_creation; 1155 } 1156 use_efi_dflts = (altsblock.fs_version == 1157 UFS_EFISTYLE4NONEFI_VERSION_2) ? 1 : 0; 1158 } else { 1159 /* 1160 * The primary superblock didn't help in determining 1161 * the fs_version. Try the first alternate superblock. 1162 */ 1163 dprintf(("DeBuG checksblock() failed - error : %d" 1164 " for sb : %d\n", ret, SBOFF/sectorsize)); 1165 rdfs((diskaddr_t)ALTSB, (int)sbsize, 1166 (char *)&altsblock); 1167 ret = checksblock(altsblock, 1); 1168 1169 if (!ret) { 1170 if (altsblock.fs_magic == MTB_UFS_MAGIC) { 1171 mtb = 'y'; 1172 goto start_fs_creation; 1173 } 1174 use_efi_dflts = (altsblock.fs_version == 1175 UFS_EFISTYLE4NONEFI_VERSION_2) ? 1 : 0; 1176 } 1177 dprintf(("DeBuG checksblock() returned : %d" 1178 " for sb : %d\n", ret, ALTSB)); 1179 } 1180 } 1181 1182 geom_nsect = nsect; 1183 geom_ntrack = ntrack; 1184 geom_cpg = cpg; 1185 dprintf(("DeBuG geom_nsect=%d, geom_ntrack=%d, geom_cpg=%d\n", 1186 geom_nsect, geom_ntrack, geom_cpg)); 1187 1188 start_fs_creation: 1189 retry_alternate_logic: 1190 invalid_sb_cnt = 0; 1191 cg_too_small = 0; 1192 if (use_efi_dflts) { 1193 nsect = DEF_SECTORS_EFI; 1194 ntrack = DEF_TRACKS_EFI; 1195 cpg = DESCPG; 1196 dprintf(("\nDeBuG Using EFI defaults\n")); 1197 } else { 1198 nsect = geom_nsect; 1199 ntrack = geom_ntrack; 1200 cpg = geom_cpg; 1201 dprintf(("\nDeBuG Using Geometry\n")); 1202 /* 1203 * 32K based on max block size of 64K, and rotational layout 1204 * test of nsect <= (256 * sectors/block). Current block size 1205 * limit is not 64K, but it's growing soon. 1206 */ 1207 range_check(&nsect, "nsect", 1, 32768, DFLNSECT, nsect_flag); 1208 /* 1209 * ntrack is the number of tracks per cylinder. 1210 * The ntrack value must be between 1 and the total number of 1211 * sectors in the file system. 1212 */ 1213 range_check(&ntrack, "ntrack", 1, 1214 fssize_db > INT_MAX ? INT_MAX : (uint32_t)fssize_db, 1215 DFLNTRAK, ntrack_flag); 1216 } 1217 1218 range_check(&apc, "apc", 0, nsect - 1, 0, apc_flag); 1219 1220 if (mtb == 'y') 1221 fragsize = bsize; 1222 1223 range_check(&fragsize, "fragsize", sectorsize, bsize, 1224 MAX(bsize / MAXFRAG, MIN(DESFRAGSIZE, bsize)), fragsize_flag); 1225 1226 if ((bsize / MAXFRAG) > fragsize) { 1227 (void) fprintf(stderr, gettext( 1228 "fragment size %ld is too small, minimum with block size %ld is %ld\n"), 1229 fragsize, bsize, bsize / MAXFRAG); 1230 (void) fprintf(stderr, 1231 gettext("mkfs: fragsize reset to minimum %ld\n"), 1232 bsize / MAXFRAG); 1233 fragsize = bsize / MAXFRAG; 1234 } 1235 1236 if (!POWEROF2(fragsize)) { 1237 (void) fprintf(stderr, 1238 gettext("fragment size must be a power of 2, not %ld\n"), 1239 fragsize); 1240 fragsize = MAX(bsize / MAXFRAG, MIN(DESFRAGSIZE, bsize)); 1241 (void) fprintf(stderr, 1242 gettext("mkfs: fragsize reset to %ld\n"), 1243 fragsize); 1244 } 1245 1246 /* At this point, bsize must be >= fragsize, so no need to check it */ 1247 1248 if (bsize < PAGESIZE) { 1249 (void) fprintf(stderr, gettext( 1250 "WARNING: filesystem block size (%ld) is smaller than " 1251 "memory page size (%ld).\nResulting filesystem can not be " 1252 "mounted on this system.\n\n"), 1253 bsize, (long)PAGESIZE); 1254 } 1255 1256 range_check(&rps, "rps", 1, 1000, DEFHZ, rps_flag); 1257 range_check(&minfree, "free", 0, 99, MINFREE, minfree_flag); 1258 range_check(&nrpos, "nrpos", 1, nsect, MIN(nsect, NRPOS), nrpos_flag); 1259 1260 /* 1261 * nbpi is variable, but 2MB seems a reasonable upper limit, 1262 * as 4MB tends to cause problems (using otherwise-default 1263 * parameters). The true limit is where we end up with one 1264 * inode per cylinder group. If this file system is being 1265 * configured for multi-terabyte access, nbpi must be at least 1MB. 1266 */ 1267 if (mtb == 'y' && nbpi < MTB_NBPI) { 1268 (void) fprintf(stderr, gettext("mkfs: bad value for nbpi: " 1269 "must be at least 1048576 for multi-terabyte, " 1270 "nbpi reset to default 1048576\n")); 1271 nbpi = MTB_NBPI; 1272 } 1273 1274 if (mtb == 'y') 1275 range_check(&nbpi, "nbpi", MTB_NBPI, 2 * MB, MTB_NBPI, 1276 nbpi_flag); 1277 else 1278 range_check(&nbpi, "nbpi", DEV_BSIZE, 2 * MB, NBPI, nbpi_flag); 1279 1280 /* 1281 * maxcpg is another variably-limited parameter. Calculate 1282 * the limit based on what we've got for its dependent 1283 * variables. Effectively, it's how much space is left in the 1284 * superblock after all the other bits are accounted for. We 1285 * only fill in sblock fields so we can use MAXIpG. 1286 * 1287 * If the calculation of maxcpg below (for the mtb == 'n' 1288 * case) is changed, update newfs as well. 1289 * 1290 * For old-style, non-MTB format file systems, use the old 1291 * algorithm for calculating the maximum cylinder group size, 1292 * even though it limits the cylinder group more than necessary. 1293 * Since layout can affect performance, we don't want to change 1294 * the default layout for non-MTB file systems at this time. 1295 * However, for MTB file systems, use the new maxcpg calculation, 1296 * which really maxes out the cylinder group size. 1297 */ 1298 1299 sblock.fs_bsize = bsize; 1300 sblock.fs_inopb = sblock.fs_bsize / sizeof (struct dinode); 1301 1302 if (mtb == 'n') { 1303 maxcpg = (bsize - sizeof (struct cg) - 1304 howmany(MAXIpG(&sblock), NBBY)) / 1305 (sizeof (long) + nrpos * sizeof (short) + 1306 nsect / (MAXFRAG * NBBY)); 1307 } else { 1308 maxcpg = compute_maxcpg(bsize, fragsize, nbpi, nrpos, 1309 nsect * ntrack); 1310 } 1311 1312 dprintf(("DeBuG cpg : %ld\n", cpg)); 1313 if (cpg == -1) 1314 cpg = maxcpg; 1315 dprintf(("DeBuG cpg : %ld\n", cpg)); 1316 1317 /* 1318 * mincpg is variable in complex ways, so we really can't 1319 * do a sane lower-end limit check at this point. 1320 */ 1321 range_check(&cpg, "cgsize", 1, maxcpg, MIN(maxcpg, DESCPG), cpg_flag); 1322 1323 /* 1324 * get the controller info 1325 */ 1326 ismdd = 0; 1327 islog = 0; 1328 islogok = 0; 1329 waslog = 0; 1330 1331 if (ioctl(fsi, DKIOCINFO, &dkcinfo) == 0) 1332 /* 1333 * if it is an MDD (disksuite) device 1334 */ 1335 if (dkcinfo.dki_ctype == DKC_MD) { 1336 ismdd++; 1337 /* 1338 * check the logging device 1339 */ 1340 if (ioctl(fsi, _FIOISLOG, NULL) == 0) { 1341 islog++; 1342 if (ioctl(fsi, _FIOISLOGOK, NULL) == 0) 1343 islogok++; 1344 } 1345 } 1346 1347 /* 1348 * Do not grow the file system, but print on stdout the maximum 1349 * size in sectors to which the file system can be increased. 1350 * The calculated size is limited by fssize_db. 1351 * Note that we don't lock the filesystem and therefore under rare 1352 * conditions (the filesystem is mounted, the free block count is 1353 * almost zero, and the superuser is still changing it) the calculated 1354 * size can be imprecise. 1355 */ 1356 if (Pflag) { 1357 (void) printf("%llu\n", probe_summaryinfo()); 1358 exit(0); 1359 } 1360 1361 /* 1362 * If we're growing an existing filesystem, then we're about 1363 * to start doing things that can require recovery efforts if 1364 * we get interrupted, so make sure we get a chance to do so. 1365 */ 1366 if (grow) { 1367 sigact.sa_handler = recover_from_sigint; 1368 sigemptyset(&sigact.sa_mask); 1369 sigact.sa_flags = SA_RESTART; 1370 1371 if (sigaction(SIGINT, &sigact, (struct sigaction *)NULL) < 0) { 1372 perror(gettext("Could not register SIGINT handler")); 1373 lockexit(3); 1374 } 1375 } 1376 1377 if (!Nflag) { 1378 /* 1379 * Check if MNTTAB is trustable 1380 */ 1381 if (statvfs64(MNTTAB, &fs) < 0) { 1382 (void) fprintf(stderr, gettext("can't statvfs %s\n"), 1383 MNTTAB); 1384 exit(32); 1385 } 1386 1387 if (strcmp(MNTTYPE_MNTFS, fs.f_basetype) != 0) { 1388 (void) fprintf(stderr, gettext( 1389 "%s file system type is not %s, can't mkfs\n"), 1390 MNTTAB, MNTTYPE_MNTFS); 1391 exit(32); 1392 } 1393 1394 special = getfullblkname(fsys); 1395 checkdev(fsys, special); 1396 1397 /* 1398 * If we found the block device name, 1399 * then check the mount table. 1400 * if mounted, and growing write lock the file system 1401 * 1402 */ 1403 if ((special != NULL) && (*special != '\0')) { 1404 if ((mnttab = fopen(MNTTAB, "r")) == NULL) { 1405 (void) fprintf(stderr, gettext( 1406 "can't open %s\n"), MNTTAB); 1407 exit(32); 1408 } 1409 while ((getmntent(mnttab, &mntp)) == NULL) { 1410 if (grow) { 1411 checkmount(&mntp, special); 1412 continue; 1413 } 1414 if (strcmp(special, mntp.mnt_special) == 0) { 1415 (void) fprintf(stderr, gettext( 1416 "%s is mounted, can't mkfs\n"), 1417 special); 1418 exit(32); 1419 } 1420 } 1421 (void) fclose(mnttab); 1422 } 1423 1424 if (directory && (ismounted == 0)) { 1425 (void) fprintf(stderr, gettext("%s is not mounted\n"), 1426 special); 1427 lockexit(32); 1428 } 1429 1430 fso = (grow) ? open64(fsys, O_WRONLY) : creat64(fsys, 0666); 1431 if (fso < 0) { 1432 saverr = errno; 1433 (void) fprintf(stderr, 1434 gettext("%s: cannot create: %s\n"), 1435 fsys, strerror(saverr)); 1436 lockexit(32); 1437 } 1438 1439 } else { 1440 1441 /* 1442 * For the -N case, a file descriptor is needed for the llseek() 1443 * in wtfs(). See the comment in wtfs() for more information. 1444 * 1445 * Get a file descriptor that's read-only so that this code 1446 * doesn't accidentally write to the file. 1447 */ 1448 fso = open64(fsys, O_RDONLY); 1449 if (fso < 0) { 1450 saverr = errno; 1451 (void) fprintf(stderr, gettext("%s: cannot open: %s\n"), 1452 fsys, strerror(saverr)); 1453 lockexit(32); 1454 } 1455 } 1456 1457 /* 1458 * seed random # generator (for ic_generation) 1459 */ 1460 #ifdef MKFS_DEBUG 1461 srand48(12962); /* reproducible results */ 1462 #else 1463 srand48((long)(time((time_t *)NULL) + getpid())); 1464 #endif 1465 1466 if (grow) { 1467 growinit(fsys); 1468 goto grow00; 1469 } 1470 1471 /* 1472 * Validate the given file system size. 1473 * Verify that its last block can actually be accessed. 1474 * 1475 * Note: it's ok to use sblock as a buffer because it is immediately 1476 * overwritten by the rdfs() of the superblock in the next line. 1477 * 1478 * ToDo: Because the size checking is done in rdfs()/wtfs(), the 1479 * error message for specifying an illegal size is very unfriendly. 1480 * In the future, one could replace the rdfs()/wtfs() calls 1481 * below with in-line calls to read() or write(). This allows better 1482 * error messages to be put in place. 1483 */ 1484 rdfs(fssize_db - 1, (int)sectorsize, (char *)&sblock); 1485 1486 /* 1487 * make the fs unmountable 1488 */ 1489 rdfs((diskaddr_t)(SBOFF / sectorsize), (int)sbsize, (char *)&sblock); 1490 sblock.fs_magic = -1; 1491 sblock.fs_clean = FSBAD; 1492 sblock.fs_state = FSOKAY - sblock.fs_time; 1493 wtfs((diskaddr_t)(SBOFF / sectorsize), (int)sbsize, (char *)&sblock); 1494 bzero(&sblock, (size_t)sbsize); 1495 1496 sblock.fs_nsect = nsect; 1497 sblock.fs_ntrak = ntrack; 1498 1499 /* 1500 * Validate specified/determined spc 1501 * and calculate minimum cylinders per group. 1502 */ 1503 1504 /* 1505 * sectors/cyl = tracks/cyl * sectors/track 1506 */ 1507 sblock.fs_spc = sblock.fs_ntrak * sblock.fs_nsect; 1508 1509 grow00: 1510 if (apc_flag) { 1511 sblock.fs_spc -= apc; 1512 } 1513 /* 1514 * Have to test for this separately from apc_flag, due to 1515 * the growfs case.... 1516 */ 1517 if (sblock.fs_spc != sblock.fs_ntrak * sblock.fs_nsect) { 1518 spc_flag = 1; 1519 } 1520 if (grow) 1521 goto grow10; 1522 1523 sblock.fs_nrpos = nrpos; 1524 sblock.fs_bsize = bsize; 1525 sblock.fs_fsize = fragsize; 1526 sblock.fs_minfree = minfree; 1527 1528 grow10: 1529 if (nbpi < sblock.fs_fsize) { 1530 (void) fprintf(stderr, gettext( 1531 "warning: wasteful data byte allocation / inode (nbpi):\n")); 1532 (void) fprintf(stderr, gettext( 1533 "%ld smaller than allocatable fragment size of %d\n"), 1534 nbpi, sblock.fs_fsize); 1535 } 1536 if (grow) 1537 goto grow20; 1538 1539 if (opt == 's') 1540 sblock.fs_optim = FS_OPTSPACE; 1541 else 1542 sblock.fs_optim = FS_OPTTIME; 1543 1544 sblock.fs_bmask = ~(sblock.fs_bsize - 1); 1545 sblock.fs_fmask = ~(sblock.fs_fsize - 1); 1546 /* 1547 * Planning now for future expansion. 1548 */ 1549 #if defined(_BIG_ENDIAN) 1550 sblock.fs_qbmask.val[0] = 0; 1551 sblock.fs_qbmask.val[1] = ~sblock.fs_bmask; 1552 sblock.fs_qfmask.val[0] = 0; 1553 sblock.fs_qfmask.val[1] = ~sblock.fs_fmask; 1554 #endif 1555 #if defined(_LITTLE_ENDIAN) 1556 sblock.fs_qbmask.val[0] = ~sblock.fs_bmask; 1557 sblock.fs_qbmask.val[1] = 0; 1558 sblock.fs_qfmask.val[0] = ~sblock.fs_fmask; 1559 sblock.fs_qfmask.val[1] = 0; 1560 #endif 1561 for (sblock.fs_bshift = 0, i = sblock.fs_bsize; i > 1; i >>= 1) 1562 sblock.fs_bshift++; 1563 for (sblock.fs_fshift = 0, i = sblock.fs_fsize; i > 1; i >>= 1) 1564 sblock.fs_fshift++; 1565 sblock.fs_frag = numfrags(&sblock, sblock.fs_bsize); 1566 for (sblock.fs_fragshift = 0, i = sblock.fs_frag; i > 1; i >>= 1) 1567 sblock.fs_fragshift++; 1568 if (sblock.fs_frag > MAXFRAG) { 1569 (void) fprintf(stderr, gettext( 1570 "fragment size %d is too small, minimum with block size %d is %d\n"), 1571 sblock.fs_fsize, sblock.fs_bsize, 1572 sblock.fs_bsize / MAXFRAG); 1573 lockexit(32); 1574 } 1575 sblock.fs_nindir = sblock.fs_bsize / sizeof (daddr32_t); 1576 sblock.fs_inopb = sblock.fs_bsize / sizeof (struct dinode); 1577 sblock.fs_nspf = sblock.fs_fsize / sectorsize; 1578 for (sblock.fs_fsbtodb = 0, i = NSPF(&sblock); i > 1; i >>= 1) 1579 sblock.fs_fsbtodb++; 1580 1581 /* 1582 * Compute the super-block, cylinder group, and inode blocks. 1583 * Note that these "blkno" are really fragment addresses. 1584 * For example, on an 8K/1K (block/fragment) system, fs_sblkno is 16, 1585 * fs_cblkno is 24, and fs_iblkno is 32. This is why CGSIZE is so 1586 * important: only 1 FS block is allocated for the cg struct (fragment 1587 * numbers 24 through 31). 1588 */ 1589 sblock.fs_sblkno = 1590 roundup(howmany(bbsize + sbsize, sblock.fs_fsize), sblock.fs_frag); 1591 sblock.fs_cblkno = (daddr32_t)(sblock.fs_sblkno + 1592 roundup(howmany(sbsize, sblock.fs_fsize), sblock.fs_frag)); 1593 sblock.fs_iblkno = sblock.fs_cblkno + sblock.fs_frag; 1594 1595 sblock.fs_cgoffset = roundup( 1596 howmany(sblock.fs_nsect, NSPF(&sblock)), sblock.fs_frag); 1597 for (sblock.fs_cgmask = -1, i = sblock.fs_ntrak; i > 1; i >>= 1) 1598 sblock.fs_cgmask <<= 1; 1599 if (!POWEROF2(sblock.fs_ntrak)) 1600 sblock.fs_cgmask <<= 1; 1601 /* 1602 * Validate specified/determined spc 1603 * and calculate minimum cylinders per group. 1604 */ 1605 1606 for (sblock.fs_cpc = NSPB(&sblock), i = sblock.fs_spc; 1607 sblock.fs_cpc > 1 && (i & 1) == 0; 1608 sblock.fs_cpc >>= 1, i >>= 1) 1609 /* void */; 1610 mincpc = sblock.fs_cpc; 1611 1612 /* if these calculations are changed, check dump_fscmd also */ 1613 bpcg = (uint64_t)sblock.fs_spc * sectorsize; 1614 inospercg = (uint64_t)roundup(bpcg / sizeof (struct dinode), 1615 INOPB(&sblock)); 1616 if (inospercg > MAXIpG(&sblock)) 1617 inospercg = MAXIpG(&sblock); 1618 used = (uint64_t)(sblock.fs_iblkno + inospercg / 1619 INOPF(&sblock)) * NSPF(&sblock); 1620 mincpgcnt = (long)howmany((uint64_t)sblock.fs_cgoffset * 1621 (~sblock.fs_cgmask) + used, sblock.fs_spc); 1622 mincpg = roundup(mincpgcnt, mincpc); 1623 /* 1624 * Insure that cylinder group with mincpg has enough space 1625 * for block maps 1626 */ 1627 sblock.fs_cpg = mincpg; 1628 sblock.fs_ipg = (int32_t)inospercg; 1629 mapcramped = 0; 1630 1631 /* 1632 * Make sure the cg struct fits within the file system block. 1633 * Use larger block sizes until it fits 1634 */ 1635 while (CGSIZE(&sblock) > sblock.fs_bsize) { 1636 mapcramped = 1; 1637 if (sblock.fs_bsize < MAXBSIZE) { 1638 sblock.fs_bsize <<= 1; 1639 if ((i & 1) == 0) { 1640 i >>= 1; 1641 } else { 1642 sblock.fs_cpc <<= 1; 1643 mincpc <<= 1; 1644 mincpg = roundup(mincpgcnt, mincpc); 1645 sblock.fs_cpg = mincpg; 1646 } 1647 sblock.fs_frag <<= 1; 1648 sblock.fs_fragshift += 1; 1649 if (sblock.fs_frag <= MAXFRAG) 1650 continue; 1651 } 1652 1653 /* 1654 * Looped far enough. The fragment is now as large as the 1655 * filesystem block! 1656 */ 1657 if (sblock.fs_fsize == sblock.fs_bsize) { 1658 (void) fprintf(stderr, gettext( 1659 "There is no block size that can support this disk\n")); 1660 lockexit(32); 1661 } 1662 1663 /* 1664 * Try a larger fragment. Double the fragment size. 1665 */ 1666 sblock.fs_frag >>= 1; 1667 sblock.fs_fragshift -= 1; 1668 sblock.fs_fsize <<= 1; 1669 sblock.fs_nspf <<= 1; 1670 } 1671 /* 1672 * Insure that cylinder group with mincpg has enough space for inodes 1673 */ 1674 inodecramped = 0; 1675 used *= sectorsize; 1676 nbytes64 = (uint64_t)mincpg * bpcg - used; 1677 inospercg = (uint64_t)roundup((nbytes64 / nbpi), INOPB(&sblock)); 1678 sblock.fs_ipg = (int32_t)inospercg; 1679 while (inospercg > MAXIpG(&sblock)) { 1680 inodecramped = 1; 1681 if (mincpc == 1 || sblock.fs_frag == 1 || 1682 sblock.fs_bsize == MINBSIZE) 1683 break; 1684 nbytes64 = (uint64_t)mincpg * bpcg - used; 1685 (void) fprintf(stderr, 1686 gettext("With a block size of %d %s %lu\n"), 1687 sblock.fs_bsize, gettext("minimum bytes per inode is"), 1688 (uint32_t)(nbytes64 / MAXIpG(&sblock) + 1)); 1689 sblock.fs_bsize >>= 1; 1690 sblock.fs_frag >>= 1; 1691 sblock.fs_fragshift -= 1; 1692 mincpc >>= 1; 1693 sblock.fs_cpg = roundup(mincpgcnt, mincpc); 1694 if (CGSIZE(&sblock) > sblock.fs_bsize) { 1695 sblock.fs_bsize <<= 1; 1696 break; 1697 } 1698 mincpg = sblock.fs_cpg; 1699 nbytes64 = (uint64_t)mincpg * bpcg - used; 1700 inospercg = (uint64_t)roundup((nbytes64 / nbpi), 1701 INOPB(&sblock)); 1702 sblock.fs_ipg = (int32_t)inospercg; 1703 } 1704 if (inodecramped) { 1705 if (inospercg > MAXIpG(&sblock)) { 1706 nbytes64 = (uint64_t)mincpg * bpcg - used; 1707 (void) fprintf(stderr, gettext( 1708 "Minimum bytes per inode is %d\n"), 1709 (uint32_t)(nbytes64 / MAXIpG(&sblock) + 1)); 1710 } else if (!mapcramped) { 1711 (void) fprintf(stderr, gettext( 1712 "With %ld bytes per inode, minimum cylinders per group is %ld\n"), 1713 nbpi, mincpg); 1714 } 1715 } 1716 if (mapcramped) { 1717 (void) fprintf(stderr, gettext( 1718 "With %d sectors per cylinder, minimum cylinders " 1719 "per group is %ld\n"), 1720 sblock.fs_spc, mincpg); 1721 } 1722 if (inodecramped || mapcramped) { 1723 /* 1724 * To make this at least somewhat comprehensible in 1725 * the world of i18n, figure out what we're going to 1726 * say and then say it all at one time. The days of 1727 * needing to scrimp on string space are behind us.... 1728 */ 1729 if ((sblock.fs_bsize != bsize) && 1730 (sblock.fs_fsize != fragsize)) { 1731 (void) fprintf(stderr, gettext( 1732 "This requires the block size to be changed from %ld to %d\n" 1733 "and the fragment size to be changed from %ld to %d\n"), 1734 bsize, sblock.fs_bsize, 1735 fragsize, sblock.fs_fsize); 1736 } else if (sblock.fs_bsize != bsize) { 1737 (void) fprintf(stderr, gettext( 1738 "This requires the block size to be changed from %ld to %d\n"), 1739 bsize, sblock.fs_bsize); 1740 } else if (sblock.fs_fsize != fragsize) { 1741 (void) fprintf(stderr, gettext( 1742 "This requires the fragment size to be changed from %ld to %d\n"), 1743 fragsize, sblock.fs_fsize); 1744 } else { 1745 (void) fprintf(stderr, gettext( 1746 "Unable to make filesystem fit with the given constraints\n")); 1747 } 1748 (void) fprintf(stderr, gettext( 1749 "Please re-run mkfs with corrected parameters\n")); 1750 lockexit(32); 1751 } 1752 /* 1753 * Calculate the number of cylinders per group 1754 */ 1755 sblock.fs_cpg = cpg; 1756 if (sblock.fs_cpg % mincpc != 0) { 1757 (void) fprintf(stderr, gettext( 1758 "Warning: cylinder groups must have a multiple " 1759 "of %ld cylinders with the given\n parameters\n"), 1760 mincpc); 1761 sblock.fs_cpg = roundup(sblock.fs_cpg, mincpc); 1762 (void) fprintf(stderr, gettext("Rounded cgsize up to %d\n"), 1763 sblock.fs_cpg); 1764 } 1765 /* 1766 * Must insure there is enough space for inodes 1767 */ 1768 /* if these calculations are changed, check dump_fscmd also */ 1769 nbytes64 = (uint64_t)sblock.fs_cpg * bpcg - used; 1770 sblock.fs_ipg = roundup((uint32_t)(nbytes64 / nbpi), INOPB(&sblock)); 1771 1772 /* 1773 * Slim down cylinders per group, until the inodes can fit. 1774 */ 1775 while (sblock.fs_ipg > MAXIpG(&sblock)) { 1776 inodecramped = 1; 1777 sblock.fs_cpg -= mincpc; 1778 nbytes64 = (uint64_t)sblock.fs_cpg * bpcg - used; 1779 sblock.fs_ipg = roundup((uint32_t)(nbytes64 / nbpi), 1780 INOPB(&sblock)); 1781 } 1782 /* 1783 * Must insure there is enough space to hold block map. 1784 * Cut down on cylinders per group, until the cg struct fits in a 1785 * filesystem block. 1786 */ 1787 while (CGSIZE(&sblock) > sblock.fs_bsize) { 1788 mapcramped = 1; 1789 sblock.fs_cpg -= mincpc; 1790 nbytes64 = (uint64_t)sblock.fs_cpg * bpcg - used; 1791 sblock.fs_ipg = roundup((uint32_t)(nbytes64 / nbpi), 1792 INOPB(&sblock)); 1793 } 1794 sblock.fs_fpg = (sblock.fs_cpg * sblock.fs_spc) / NSPF(&sblock); 1795 if ((sblock.fs_cpg * sblock.fs_spc) % NSPB(&sblock) != 0) { 1796 (void) fprintf(stderr, 1797 gettext("newfs: panic (fs_cpg * fs_spc) %% NSPF != 0\n")); 1798 lockexit(32); 1799 } 1800 if (sblock.fs_cpg < mincpg) { 1801 (void) fprintf(stderr, gettext( 1802 "With the given parameters, cgsize must be at least %ld; please re-run mkfs\n"), 1803 mincpg); 1804 lockexit(32); 1805 } 1806 sblock.fs_cgsize = fragroundup(&sblock, CGSIZE(&sblock)); 1807 grow20: 1808 /* 1809 * Now have size for file system and nsect and ntrak. 1810 * Determine number of cylinders and blocks in the file system. 1811 */ 1812 fssize_frag = (int64_t)dbtofsb(&sblock, fssize_db); 1813 if (fssize_frag > INT_MAX) { 1814 (void) fprintf(stderr, gettext( 1815 "There are too many fragments in the system, increase fragment size\n"), 1816 mincpg); 1817 lockexit(32); 1818 } 1819 sblock.fs_size = (int32_t)fssize_frag; 1820 sblock.fs_ncyl = (int32_t)(fssize_frag * NSPF(&sblock) / sblock.fs_spc); 1821 if (fssize_frag * NSPF(&sblock) > 1822 (uint64_t)sblock.fs_ncyl * sblock.fs_spc) { 1823 sblock.fs_ncyl++; 1824 warn = 1; 1825 } 1826 if (sblock.fs_ncyl < 1) { 1827 (void) fprintf(stderr, gettext( 1828 "file systems must have at least one cylinder\n")); 1829 lockexit(32); 1830 } 1831 if (grow) 1832 goto grow30; 1833 /* 1834 * Determine feasability/values of rotational layout tables. 1835 * 1836 * The size of the rotational layout tables is limited by the size 1837 * of the file system block, fs_bsize. The amount of space 1838 * available for tables is calculated as (fs_bsize - sizeof (struct 1839 * fs)). The size of these tables is inversely proportional to the 1840 * block size of the file system. The size increases if sectors per 1841 * track are not powers of two, because more cylinders must be 1842 * described by the tables before the rotational pattern repeats 1843 * (fs_cpc). 1844 */ 1845 sblock.fs_postblformat = FS_DYNAMICPOSTBLFMT; 1846 sblock.fs_sbsize = fragroundup(&sblock, sizeof (struct fs)); 1847 sblock.fs_npsect = sblock.fs_nsect; 1848 if (sblock.fs_ntrak == 1) { 1849 sblock.fs_cpc = 0; 1850 goto next; 1851 } 1852 postblsize = sblock.fs_nrpos * sblock.fs_cpc * sizeof (short); 1853 rotblsize = sblock.fs_cpc * sblock.fs_spc / NSPB(&sblock); 1854 totalsbsize = sizeof (struct fs) + rotblsize; 1855 1856 /* do static allocation if nrpos == 8 and fs_cpc == 16 */ 1857 if (sblock.fs_nrpos == 8 && sblock.fs_cpc <= 16) { 1858 /* use old static table space */ 1859 sblock.fs_postbloff = (char *)(&sblock.fs_opostbl[0][0]) - 1860 (char *)(&sblock.fs_link); 1861 sblock.fs_rotbloff = &sblock.fs_space[0] - 1862 (uchar_t *)(&sblock.fs_link); 1863 } else { 1864 /* use 4.3 dynamic table space */ 1865 sblock.fs_postbloff = &sblock.fs_space[0] - 1866 (uchar_t *)(&sblock.fs_link); 1867 sblock.fs_rotbloff = sblock.fs_postbloff + postblsize; 1868 totalsbsize += postblsize; 1869 } 1870 if (totalsbsize > sblock.fs_bsize || 1871 sblock.fs_nsect > (1 << NBBY) * NSPB(&sblock)) { 1872 (void) fprintf(stderr, gettext( 1873 "Warning: insufficient space in super block for\n" 1874 "rotational layout tables with nsect %d, ntrack %d, " 1875 "and nrpos %d.\nOmitting tables - file system " 1876 "performance may be impaired.\n"), 1877 sblock.fs_nsect, sblock.fs_ntrak, sblock.fs_nrpos); 1878 1879 /* 1880 * Setting fs_cpc to 0 tells alloccgblk() in ufs_alloc.c to 1881 * ignore the positional layout table and rotational 1882 * position table. 1883 */ 1884 sblock.fs_cpc = 0; 1885 goto next; 1886 } 1887 sblock.fs_sbsize = fragroundup(&sblock, totalsbsize); 1888 1889 1890 /* 1891 * calculate the available blocks for each rotational position 1892 */ 1893 for (cylno = 0; cylno < sblock.fs_cpc; cylno++) 1894 for (rpos = 0; rpos < sblock.fs_nrpos; rpos++) 1895 fs_postbl(&sblock, cylno)[rpos] = -1; 1896 for (i = (rotblsize - 1) * sblock.fs_frag; 1897 i >= 0; i -= sblock.fs_frag) { 1898 cylno = cbtocylno(&sblock, i); 1899 rpos = cbtorpos(&sblock, i); 1900 blk = fragstoblks(&sblock, i); 1901 if (fs_postbl(&sblock, cylno)[rpos] == -1) 1902 fs_rotbl(&sblock)[blk] = 0; 1903 else 1904 fs_rotbl(&sblock)[blk] = 1905 fs_postbl(&sblock, cylno)[rpos] - blk; 1906 fs_postbl(&sblock, cylno)[rpos] = blk; 1907 } 1908 next: 1909 grow30: 1910 /* 1911 * Compute/validate number of cylinder groups. 1912 * Note that if an excessively large filesystem is specified 1913 * (e.g., more than 16384 cylinders for an 8K filesystem block), it 1914 * does not get detected until checksummarysize() 1915 */ 1916 sblock.fs_ncg = sblock.fs_ncyl / sblock.fs_cpg; 1917 if (sblock.fs_ncyl % sblock.fs_cpg) 1918 sblock.fs_ncg++; 1919 sblock.fs_dblkno = sblock.fs_iblkno + sblock.fs_ipg / INOPF(&sblock); 1920 i = MIN(~sblock.fs_cgmask, sblock.fs_ncg - 1); 1921 ibpcl = cgdmin(&sblock, i) - cgbase(&sblock, i); 1922 if (ibpcl >= sblock.fs_fpg) { 1923 (void) fprintf(stderr, gettext( 1924 "inode blocks/cyl group (%d) >= data blocks (%d)\n"), 1925 cgdmin(&sblock, i) - cgbase(&sblock, i) / sblock.fs_frag, 1926 sblock.fs_fpg / sblock.fs_frag); 1927 if ((ibpcl < 0) || (sblock.fs_fpg < 0)) { 1928 (void) fprintf(stderr, gettext( 1929 "number of cylinders per cylinder group (%d) must be decreased.\n"), 1930 sblock.fs_cpg); 1931 } else { 1932 (void) fprintf(stderr, gettext( 1933 "number of cylinders per cylinder group (%d) must be increased.\n"), 1934 sblock.fs_cpg); 1935 } 1936 (void) fprintf(stderr, gettext( 1937 "Note that cgsize may have been adjusted to allow struct cg to fit.\n")); 1938 lockexit(32); 1939 } 1940 j = sblock.fs_ncg - 1; 1941 if ((i = fssize_frag - j * sblock.fs_fpg) < sblock.fs_fpg && 1942 cgdmin(&sblock, j) - cgbase(&sblock, j) > i) { 1943 (void) fprintf(stderr, gettext( 1944 "Warning: inode blocks/cyl group (%d) >= data " 1945 "blocks (%ld) in last\n cylinder group. This " 1946 "implies %ld sector(s) cannot be allocated.\n"), 1947 (cgdmin(&sblock, j) - cgbase(&sblock, j)) / sblock.fs_frag, 1948 i / sblock.fs_frag, i * NSPF(&sblock)); 1949 /* 1950 * If there is only one cylinder group and that is not even 1951 * big enough to hold the inodes, exit. 1952 */ 1953 if (sblock.fs_ncg == 1) 1954 cg_too_small = 1; 1955 sblock.fs_ncg--; 1956 sblock.fs_ncyl -= sblock.fs_ncyl % sblock.fs_cpg; 1957 sblock.fs_size = fssize_frag = 1958 (int64_t)sblock.fs_ncyl * (int64_t)sblock.fs_spc / 1959 (int64_t)NSPF(&sblock); 1960 warn = 0; 1961 } 1962 if (warn && !spc_flag) { 1963 (void) fprintf(stderr, gettext( 1964 "Warning: %d sector(s) in last cylinder unallocated\n"), 1965 sblock.fs_spc - (uint32_t)(fssize_frag * NSPF(&sblock) - 1966 (uint64_t)(sblock.fs_ncyl - 1) * sblock.fs_spc)); 1967 } 1968 /* 1969 * fill in remaining fields of the super block 1970 */ 1971 1972 /* 1973 * The csum records are stored in cylinder group 0, starting at 1974 * cgdmin, the first data block. 1975 */ 1976 sblock.fs_csaddr = cgdmin(&sblock, 0); 1977 sblock.fs_cssize = 1978 fragroundup(&sblock, sblock.fs_ncg * sizeof (struct csum)); 1979 i = sblock.fs_bsize / sizeof (struct csum); 1980 sblock.fs_csmask = ~(i - 1); 1981 for (sblock.fs_csshift = 0; i > 1; i >>= 1) 1982 sblock.fs_csshift++; 1983 fscs = (struct csum *)calloc(1, sblock.fs_cssize); 1984 1985 checksummarysize(); 1986 if (mtb == 'y') { 1987 sblock.fs_magic = MTB_UFS_MAGIC; 1988 sblock.fs_version = MTB_UFS_VERSION_1; 1989 } else { 1990 sblock.fs_magic = FS_MAGIC; 1991 if (use_efi_dflts) 1992 sblock.fs_version = UFS_EFISTYLE4NONEFI_VERSION_2; 1993 else 1994 sblock.fs_version = UFS_VERSION_MIN; 1995 } 1996 1997 if (grow) { 1998 bcopy((caddr_t)grow_fscs, (caddr_t)fscs, (int)grow_fs_cssize); 1999 extendsummaryinfo(); 2000 goto grow40; 2001 } 2002 sblock.fs_rotdelay = rotdelay; 2003 sblock.fs_maxcontig = maxcontig; 2004 sblock.fs_maxbpg = MAXBLKPG(sblock.fs_bsize); 2005 2006 sblock.fs_rps = rps; 2007 sblock.fs_cgrotor = 0; 2008 sblock.fs_cstotal.cs_ndir = 0; 2009 sblock.fs_cstotal.cs_nbfree = 0; 2010 sblock.fs_cstotal.cs_nifree = 0; 2011 sblock.fs_cstotal.cs_nffree = 0; 2012 sblock.fs_fmod = 0; 2013 sblock.fs_ronly = 0; 2014 sblock.fs_time = mkfstime; 2015 sblock.fs_state = FSOKAY - sblock.fs_time; 2016 sblock.fs_clean = FSCLEAN; 2017 grow40: 2018 2019 /* 2020 * If all that's needed is a dump of the superblock we 2021 * would use by default, we've got it now. So, splat it 2022 * out and leave. 2023 */ 2024 if (rflag) { 2025 dump_sblock(); 2026 lockexit(0); 2027 } 2028 /* 2029 * Dump out summary information about file system. 2030 */ 2031 (void) fprintf(stderr, gettext( 2032 "%s:\t%lld sectors in %d cylinders of %d tracks, %d sectors\n"), 2033 fsys, (uint64_t)sblock.fs_size * NSPF(&sblock), sblock.fs_ncyl, 2034 sblock.fs_ntrak, sblock.fs_nsect); 2035 (void) fprintf(stderr, gettext( 2036 "\t%.1fMB in %d cyl groups (%d c/g, %.2fMB/g, %d i/g)\n"), 2037 (float)sblock.fs_size * sblock.fs_fsize / MB, sblock.fs_ncg, 2038 sblock.fs_cpg, (float)sblock.fs_fpg * sblock.fs_fsize / MB, 2039 sblock.fs_ipg); 2040 2041 tmpbuf = calloc(sblock.fs_ncg / 50 + 500, 1); 2042 if (tmpbuf == NULL) { 2043 perror("calloc"); 2044 lockexit(32); 2045 } 2046 if (cg_too_small) { 2047 (void) fprintf(stderr, gettext("File system creation failed. " 2048 "There is only one cylinder group and\nthat is " 2049 "not even big enough to hold the inodes.\n")); 2050 lockexit(32); 2051 } 2052 /* 2053 * Now build the cylinders group blocks and 2054 * then print out indices of cylinder groups. 2055 */ 2056 tprintf(gettext( 2057 "super-block backups (for fsck -F ufs -o b=#) at:\n")); 2058 for (width = cylno = 0; cylno < sblock.fs_ncg && cylno < 10; cylno++) { 2059 if ((grow == 0) || (cylno >= grow_fs_ncg)) 2060 initcg(cylno); 2061 num = fsbtodb(&sblock, (uint64_t)cgsblock(&sblock, cylno)); 2062 /* 2063 * If Nflag and if the disk is larger than the CHSLIMIT, 2064 * then sanity test the superblocks before reporting. If there 2065 * are too many superblocks which look insane, we have 2066 * to retry with alternate logic. If both methods have 2067 * failed, then our efforts to arrive at alternate 2068 * superblocks failed, so complain and exit. 2069 */ 2070 if (Nflag && retry) { 2071 skip_this_sb = 0; 2072 rdfs((diskaddr_t)num, sbsize, (char *)&altsblock); 2073 ret = checksblock(altsblock, 1); 2074 if (ret) { 2075 skip_this_sb = 1; 2076 invalid_sb_cnt++; 2077 dprintf(("DeBuG checksblock() failed - error : %d" 2078 " for sb : %llu invalid_sb_cnt : %d\n", 2079 ret, num, invalid_sb_cnt)); 2080 } else { 2081 /* 2082 * Though the superblock looks sane, verify if the 2083 * fs_version in the superblock and the logic that 2084 * we are using to arrive at the superblocks match. 2085 */ 2086 if (use_efi_dflts && altsblock.fs_version 2087 != UFS_EFISTYLE4NONEFI_VERSION_2) { 2088 skip_this_sb = 1; 2089 invalid_sb_cnt++; 2090 } 2091 } 2092 if (invalid_sb_cnt >= INVALIDSBLIMIT) { 2093 if (retry > 1) { 2094 (void) fprintf(stderr, gettext( 2095 "Error determining alternate " 2096 "superblock locations\n")); 2097 free(tmpbuf); 2098 lockexit(32); 2099 } 2100 retry++; 2101 use_efi_dflts = !use_efi_dflts; 2102 free(tmpbuf); 2103 goto retry_alternate_logic; 2104 } 2105 if (skip_this_sb) 2106 continue; 2107 } 2108 (void) sprintf(pbuf, " %llu,", num); 2109 plen = strlen(pbuf); 2110 if ((width + plen) > (WIDTH - 1)) { 2111 width = plen; 2112 tprintf("\n"); 2113 } else { 2114 width += plen; 2115 } 2116 if (Nflag && retry) 2117 (void) strncat(tmpbuf, pbuf, strlen(pbuf)); 2118 else 2119 (void) fprintf(stderr, "%s", pbuf); 2120 } 2121 tprintf("\n"); 2122 2123 remaining_cg = sblock.fs_ncg - cylno; 2124 2125 /* 2126 * If there are more than 300 cylinder groups still to be 2127 * initialized, print a "." for every 50 cylinder groups. 2128 */ 2129 if (remaining_cg > 300) { 2130 tprintf(gettext("Initializing cylinder groups:\n")); 2131 do_dot = 1; 2132 } 2133 2134 /* 2135 * Now initialize all cylinder groups between the first ten 2136 * and the last ten. 2137 * 2138 * If the number of cylinder groups was less than 10, all of the 2139 * cylinder group offsets would have printed in the last loop 2140 * and cylno will already be equal to sblock.fs_ncg and so this 2141 * loop will not be entered. If there are less than 20 cylinder 2142 * groups, cylno is already less than fs_ncg - 10, so this loop 2143 * won't be entered in that case either. 2144 */ 2145 2146 i = 0; 2147 for (; cylno < sblock.fs_ncg - 10; cylno++) { 2148 if ((grow == 0) || (cylno >= grow_fs_ncg)) 2149 initcg(cylno); 2150 if (do_dot && cylno % 50 == 0) { 2151 tprintf("."); 2152 i++; 2153 if (i == WIDTH - 1) { 2154 tprintf("\n"); 2155 i = 0; 2156 } 2157 } 2158 } 2159 2160 /* 2161 * Now print the cylinder group offsets for the last 10 2162 * cylinder groups, if any are left. 2163 */ 2164 2165 if (do_dot) { 2166 tprintf(gettext( 2167 "\nsuper-block backups for last 10 cylinder groups at:\n")); 2168 } 2169 for (width = 0; cylno < sblock.fs_ncg; cylno++) { 2170 if ((grow == 0) || (cylno >= grow_fs_ncg)) 2171 initcg(cylno); 2172 num = fsbtodb(&sblock, (uint64_t)cgsblock(&sblock, cylno)); 2173 if (Nflag && retry) { 2174 skip_this_sb = 0; 2175 rdfs((diskaddr_t)num, sbsize, (char *)&altsblock); 2176 ret = checksblock(altsblock, 1); 2177 if (ret) { 2178 skip_this_sb = 1; 2179 invalid_sb_cnt++; 2180 dprintf(("DeBuG checksblock() failed - error : %d" 2181 " for sb : %llu invalid_sb_cnt : %d\n", 2182 ret, num, invalid_sb_cnt)); 2183 } else { 2184 /* 2185 * Though the superblock looks sane, verify if the 2186 * fs_version in the superblock and the logic that 2187 * we are using to arrive at the superblocks match. 2188 */ 2189 if (use_efi_dflts && altsblock.fs_version 2190 != UFS_EFISTYLE4NONEFI_VERSION_2) { 2191 skip_this_sb = 1; 2192 invalid_sb_cnt++; 2193 } 2194 } 2195 if (invalid_sb_cnt >= INVALIDSBLIMIT) { 2196 if (retry > 1) { 2197 (void) fprintf(stderr, gettext( 2198 "Error determining alternate " 2199 "superblock locations\n")); 2200 free(tmpbuf); 2201 lockexit(32); 2202 } 2203 retry++; 2204 use_efi_dflts = !use_efi_dflts; 2205 free(tmpbuf); 2206 goto retry_alternate_logic; 2207 } 2208 if (skip_this_sb) 2209 continue; 2210 } 2211 /* Don't print ',' for the last superblock */ 2212 if (cylno == sblock.fs_ncg-1) 2213 (void) sprintf(pbuf, " %llu", num); 2214 else 2215 (void) sprintf(pbuf, " %llu,", num); 2216 plen = strlen(pbuf); 2217 if ((width + plen) > (WIDTH - 1)) { 2218 width = plen; 2219 tprintf("\n"); 2220 } else { 2221 width += plen; 2222 } 2223 if (Nflag && retry) 2224 (void) strncat(tmpbuf, pbuf, strlen(pbuf)); 2225 else 2226 (void) fprintf(stderr, "%s", pbuf); 2227 } 2228 tprintf("\n"); 2229 if (Nflag) { 2230 if (retry) 2231 (void) fprintf(stderr, "%s", tmpbuf); 2232 free(tmpbuf); 2233 lockexit(0); 2234 } 2235 2236 free(tmpbuf); 2237 if (grow) 2238 goto grow50; 2239 2240 /* 2241 * Now construct the initial file system, 2242 * then write out the super-block. 2243 */ 2244 fsinit(); 2245 grow50: 2246 /* 2247 * write the superblock and csum information 2248 */ 2249 wtsb(); 2250 2251 /* 2252 * extend the last cylinder group in the original file system 2253 */ 2254 if (grow) { 2255 extendcg(grow_fs_ncg-1); 2256 wtsb(); 2257 } 2258 2259 /* 2260 * Write out the duplicate super blocks to the first 10 2261 * cylinder groups (or fewer, if there are fewer than 10 2262 * cylinder groups). 2263 */ 2264 for (cylno = 0; cylno < sblock.fs_ncg && cylno < 10; cylno++) 2265 awtfs(fsbtodb(&sblock, (uint64_t)cgsblock(&sblock, cylno)), 2266 (int)sbsize, (char *)&sblock, SAVE); 2267 2268 /* 2269 * Now write out duplicate super blocks to the remaining 2270 * cylinder groups. In the case of multi-terabyte file 2271 * systems, just write out the super block to the last ten 2272 * cylinder groups (or however many are left). 2273 */ 2274 if (mtb == 'y') { 2275 if (sblock.fs_ncg <= 10) 2276 cylno = sblock.fs_ncg; 2277 else if (sblock.fs_ncg <= 20) 2278 cylno = 10; 2279 else 2280 cylno = sblock.fs_ncg - 10; 2281 } 2282 2283 for (; cylno < sblock.fs_ncg; cylno++) 2284 awtfs(fsbtodb(&sblock, (uint64_t)cgsblock(&sblock, cylno)), 2285 (int)sbsize, (char *)&sblock, SAVE); 2286 2287 /* 2288 * Flush out all the AIO writes we've done. It's not 2289 * necessary to do this explicitly, but it's the only 2290 * way to report any errors from those writes. 2291 */ 2292 flush_writes(); 2293 2294 /* 2295 * set clean flag 2296 */ 2297 if (grow) 2298 sblock.fs_clean = grow_fs_clean; 2299 else 2300 sblock.fs_clean = FSCLEAN; 2301 sblock.fs_time = mkfstime; 2302 sblock.fs_state = FSOKAY - sblock.fs_time; 2303 wtfs((diskaddr_t)(SBOFF / sectorsize), sbsize, (char *)&sblock); 2304 isbad = 0; 2305 2306 if (fsync(fso) == -1) { 2307 saverr = errno; 2308 (void) fprintf(stderr, 2309 gettext("mkfs: fsync failed on write disk: %s\n"), 2310 strerror(saverr)); 2311 /* we're just cleaning up, so keep going */ 2312 } 2313 if (close(fsi) == -1) { 2314 saverr = errno; 2315 (void) fprintf(stderr, 2316 gettext("mkfs: close failed on read disk: %s\n"), 2317 strerror(saverr)); 2318 /* we're just cleaning up, so keep going */ 2319 } 2320 if (close(fso) == -1) { 2321 saverr = errno; 2322 (void) fprintf(stderr, 2323 gettext("mkfs: close failed on write disk: %s\n"), 2324 strerror(saverr)); 2325 /* we're just cleaning up, so keep going */ 2326 } 2327 fsi = fso = -1; 2328 2329 #ifndef STANDALONE 2330 lockexit(0); 2331 #endif 2332 2333 return (0); 2334 } 2335 2336 /* 2337 * Figure out how big the partition we're dealing with is. 2338 * The value returned is in disk blocks (sectors); 2339 */ 2340 static diskaddr_t 2341 get_max_size(int fd) 2342 { 2343 struct vtoc vtoc; 2344 dk_gpt_t *efi_vtoc; 2345 diskaddr_t slicesize; 2346 2347 int index = read_vtoc(fd, &vtoc); 2348 2349 if (index >= 0) { 2350 label_type = LABEL_TYPE_VTOC; 2351 } else { 2352 if (index == VT_ENOTSUP || index == VT_ERROR) { 2353 /* it might be an EFI label */ 2354 index = efi_alloc_and_read(fd, &efi_vtoc); 2355 label_type = LABEL_TYPE_EFI; 2356 } 2357 } 2358 2359 if (index < 0) { 2360 switch (index) { 2361 case VT_ERROR: 2362 break; 2363 case VT_EIO: 2364 errno = EIO; 2365 break; 2366 case VT_EINVAL: 2367 errno = EINVAL; 2368 } 2369 perror(gettext("Can not determine partition size")); 2370 lockexit(32); 2371 } 2372 2373 if (label_type == LABEL_TYPE_EFI) { 2374 slicesize = efi_vtoc->efi_parts[index].p_size; 2375 efi_free(efi_vtoc); 2376 } else { 2377 /* 2378 * In the vtoc struct, p_size is a 32-bit signed quantity. 2379 * In the dk_gpt struct (efi's version of the vtoc), p_size 2380 * is an unsigned 64-bit quantity. By casting the vtoc's 2381 * psize to an unsigned 32-bit quantity, it will be copied 2382 * to 'slicesize' (an unsigned 64-bit diskaddr_t) without 2383 * sign extension. 2384 */ 2385 2386 slicesize = (uint32_t)vtoc.v_part[index].p_size; 2387 } 2388 2389 dprintf(("DeBuG get_max_size index = %d, p_size = %lld, dolimit = %d\n", 2390 index, slicesize, (slicesize > FS_MAX))); 2391 2392 /* 2393 * The next line limits a UFS file system to the maximum 2394 * supported size. 2395 */ 2396 2397 if (slicesize > FS_MAX) 2398 return (FS_MAX); 2399 return (slicesize); 2400 } 2401 2402 static long 2403 get_max_track_size(int fd) 2404 { 2405 struct dk_cinfo ci; 2406 long track_size = -1; 2407 2408 if (ioctl(fd, DKIOCINFO, &ci) == 0) { 2409 track_size = ci.dki_maxtransfer * DEV_BSIZE; 2410 } 2411 2412 if ((track_size < 0)) { 2413 int error = 0; 2414 int maxphys; 2415 int gotit = 0; 2416 2417 gotit = fsgetmaxphys(&maxphys, &error); 2418 if (gotit) { 2419 track_size = MIN(MB, maxphys); 2420 } else { 2421 (void) fprintf(stderr, gettext( 2422 "Warning: Could not get system value for maxphys. The value for\n" 2423 "maxcontig will default to 1MB.\n")); 2424 track_size = MB; 2425 } 2426 } 2427 return (track_size); 2428 } 2429 2430 /* 2431 * Initialize a cylinder group. 2432 */ 2433 static void 2434 initcg(int cylno) 2435 { 2436 diskaddr_t cbase, d; 2437 diskaddr_t dlower; /* last data block before cg metadata */ 2438 diskaddr_t dupper; /* first data block after cg metadata */ 2439 diskaddr_t dmax; 2440 int64_t i; 2441 struct csum *cs; 2442 struct dinode *inode_buffer; 2443 int size; 2444 2445 /* 2446 * Variables used to store intermediate results as a part of 2447 * the internal implementation of the cbtocylno() macros. 2448 */ 2449 diskaddr_t bno; /* UFS block number (not sector number) */ 2450 int cbcylno; /* current cylinder number */ 2451 int cbcylno_sect; /* sector offset within cylinder */ 2452 int cbsect_incr; /* amount to increment sector offset */ 2453 2454 /* 2455 * Variables used to store intermediate results as a part of 2456 * the internal implementation of the cbtorpos() macros. 2457 */ 2458 short *cgblks; /* pointer to array of free blocks in cg */ 2459 int trackrpos; /* tmp variable for rotation position */ 2460 int trackoff; /* offset within a track */ 2461 int trackoff_incr; /* amount to increment trackoff */ 2462 int rpos; /* rotation position of current block */ 2463 int rpos_incr; /* amount to increment rpos per block */ 2464 2465 union cgun *icgun; /* local pointer to a cg summary block */ 2466 #define icg (icgun->cg) 2467 2468 icgun = (union cgun *)getbuf(&cgsumbuf, sizeof (union cgun)); 2469 2470 /* 2471 * Determine block bounds for cylinder group. 2472 * Allow space for super block summary information in first 2473 * cylinder group. 2474 */ 2475 cbase = cgbase(&sblock, cylno); 2476 dmax = cbase + sblock.fs_fpg; 2477 if (dmax > sblock.fs_size) /* last cg may be smaller than normal */ 2478 dmax = sblock.fs_size; 2479 dlower = cgsblock(&sblock, cylno) - cbase; 2480 dupper = cgdmin(&sblock, cylno) - cbase; 2481 if (cylno == 0) 2482 dupper += howmany(sblock.fs_cssize, sblock.fs_fsize); 2483 cs = fscs + cylno; 2484 icg.cg_time = mkfstime; 2485 icg.cg_magic = CG_MAGIC; 2486 icg.cg_cgx = cylno; 2487 /* last one gets whatever's left */ 2488 if (cylno == sblock.fs_ncg - 1) 2489 icg.cg_ncyl = sblock.fs_ncyl - (sblock.fs_cpg * cylno); 2490 else 2491 icg.cg_ncyl = sblock.fs_cpg; 2492 icg.cg_niblk = sblock.fs_ipg; 2493 icg.cg_ndblk = dmax - cbase; 2494 icg.cg_cs.cs_ndir = 0; 2495 icg.cg_cs.cs_nffree = 0; 2496 icg.cg_cs.cs_nbfree = 0; 2497 icg.cg_cs.cs_nifree = 0; 2498 icg.cg_rotor = 0; 2499 icg.cg_frotor = 0; 2500 icg.cg_irotor = 0; 2501 icg.cg_btotoff = &icg.cg_space[0] - (uchar_t *)(&icg.cg_link); 2502 icg.cg_boff = icg.cg_btotoff + sblock.fs_cpg * sizeof (long); 2503 icg.cg_iusedoff = icg.cg_boff + 2504 sblock.fs_cpg * sblock.fs_nrpos * sizeof (short); 2505 icg.cg_freeoff = icg.cg_iusedoff + howmany(sblock.fs_ipg, NBBY); 2506 icg.cg_nextfreeoff = icg.cg_freeoff + 2507 howmany(sblock.fs_cpg * sblock.fs_spc / NSPF(&sblock), NBBY); 2508 for (i = 0; i < sblock.fs_frag; i++) { 2509 icg.cg_frsum[i] = 0; 2510 } 2511 bzero((caddr_t)cg_inosused(&icg), icg.cg_freeoff - icg.cg_iusedoff); 2512 icg.cg_cs.cs_nifree += sblock.fs_ipg; 2513 if (cylno == 0) 2514 for (i = 0; i < UFSROOTINO; i++) { 2515 setbit(cg_inosused(&icg), i); 2516 icg.cg_cs.cs_nifree--; 2517 } 2518 2519 /* 2520 * Initialize all the inodes in the cylinder group using 2521 * random numbers. 2522 */ 2523 size = sblock.fs_ipg * sizeof (struct dinode); 2524 inode_buffer = (struct dinode *)getbuf(&inodebuf, size); 2525 2526 for (i = 0; i < sblock.fs_ipg; i++) { 2527 IRANDOMIZE(&(inode_buffer[i].di_ic)); 2528 } 2529 2530 /* 2531 * Write all inodes in a single write for performance. 2532 */ 2533 awtfs(fsbtodb(&sblock, (uint64_t)cgimin(&sblock, cylno)), (int)size, 2534 (char *)inode_buffer, RELEASE); 2535 2536 bzero((caddr_t)cg_blktot(&icg), icg.cg_boff - icg.cg_btotoff); 2537 bzero((caddr_t)cg_blks(&sblock, &icg, 0), 2538 icg.cg_iusedoff - icg.cg_boff); 2539 bzero((caddr_t)cg_blksfree(&icg), icg.cg_nextfreeoff - icg.cg_freeoff); 2540 2541 if (cylno > 0) { 2542 for (d = 0; d < dlower; d += sblock.fs_frag) { 2543 setblock(&sblock, cg_blksfree(&icg), d/sblock.fs_frag); 2544 icg.cg_cs.cs_nbfree++; 2545 cg_blktot(&icg)[cbtocylno(&sblock, d)]++; 2546 cg_blks(&sblock, &icg, cbtocylno(&sblock, d)) 2547 [cbtorpos(&sblock, d)]++; 2548 } 2549 sblock.fs_dsize += dlower; 2550 } 2551 sblock.fs_dsize += icg.cg_ndblk - dupper; 2552 if ((i = dupper % sblock.fs_frag) != 0) { 2553 icg.cg_frsum[sblock.fs_frag - i]++; 2554 for (d = dupper + sblock.fs_frag - i; dupper < d; dupper++) { 2555 setbit(cg_blksfree(&icg), dupper); 2556 icg.cg_cs.cs_nffree++; 2557 } 2558 } 2559 2560 /* 2561 * WARNING: The following code is somewhat confusing, but 2562 * results in a substantial performance improvement in mkfs. 2563 * 2564 * Instead of using cbtocylno() and cbtorpos() macros, we 2565 * keep track of all the intermediate state of those macros 2566 * in some variables. This allows simple addition to be 2567 * done to calculate the results as we step through the 2568 * blocks in an orderly fashion instead of the slower 2569 * multiplication and division the macros are forced to 2570 * used so they can support random input. (Multiplication, 2571 * division, and remainder operations typically take about 2572 * 10x as many processor cycles as other operations.) 2573 * 2574 * The basic idea is to take code: 2575 * 2576 * for (x = starting_x; x < max; x++) 2577 * y = (x * c) / z 2578 * 2579 * and rewrite it to take advantage of the fact that 2580 * the variable x is incrementing in an orderly way: 2581 * 2582 * intermediate = starting_x * c 2583 * yval = intermediate / z 2584 * for (x = starting_x; x < max; x++) { 2585 * y = yval; 2586 * intermediate += c 2587 * if (intermediate > z) { 2588 * yval++; 2589 * intermediate -= z 2590 * } 2591 * } 2592 * 2593 * Performance has improved as much as 4X using this code. 2594 */ 2595 2596 /* 2597 * Initialize the starting points for all the cbtocylno() 2598 * macro variables and figure out the increments needed each 2599 * time through the loop. 2600 */ 2601 cbcylno_sect = dupper * NSPF(&sblock); 2602 cbsect_incr = sblock.fs_frag * NSPF(&sblock); 2603 cbcylno = cbcylno_sect / sblock.fs_spc; 2604 cbcylno_sect %= sblock.fs_spc; 2605 cgblks = cg_blks(&sblock, &icg, cbcylno); 2606 bno = dupper / sblock.fs_frag; 2607 2608 /* 2609 * Initialize the starting points for all the cbtorpos() 2610 * macro variables and figure out the increments needed each 2611 * time through the loop. 2612 * 2613 * It's harder to simplify the cbtorpos() macro if there were 2614 * alternate sectors specified (or if they previously existed 2615 * in the growfs case). Since this is rare, we just revert to 2616 * using the macros in this case and skip the variable setup. 2617 */ 2618 if (!spc_flag) { 2619 trackrpos = (cbcylno_sect % sblock.fs_nsect) * sblock.fs_nrpos; 2620 rpos = trackrpos / sblock.fs_nsect; 2621 trackoff = trackrpos % sblock.fs_nsect; 2622 trackoff_incr = cbsect_incr * sblock.fs_nrpos; 2623 rpos_incr = (trackoff_incr / sblock.fs_nsect) % sblock.fs_nrpos; 2624 trackoff_incr = trackoff_incr % sblock.fs_nsect; 2625 } 2626 2627 /* 2628 * Loop through all the blocks, marking them free and 2629 * updating totals kept in the superblock and cg summary. 2630 */ 2631 for (d = dupper; d + sblock.fs_frag <= dmax - cbase; ) { 2632 setblock(&sblock, cg_blksfree(&icg), bno); 2633 icg.cg_cs.cs_nbfree++; 2634 2635 cg_blktot(&icg)[cbcylno]++; 2636 2637 if (!spc_flag) 2638 cgblks[rpos]++; 2639 else 2640 cg_blks(&sblock, &icg, cbtocylno(&sblock, d)) 2641 [cbtorpos(&sblock, d)]++; 2642 2643 d += sblock.fs_frag; 2644 bno++; 2645 2646 /* 2647 * Increment the sector offset within the cylinder 2648 * for the cbtocylno() macro reimplementation. If 2649 * we're beyond the end of the cylinder, update the 2650 * cylinder number, calculate the offset in the 2651 * new cylinder, and update the cgblks pointer 2652 * to the next rotational position. 2653 */ 2654 cbcylno_sect += cbsect_incr; 2655 if (cbcylno_sect >= sblock.fs_spc) { 2656 cbcylno++; 2657 cbcylno_sect -= sblock.fs_spc; 2658 cgblks += sblock.fs_nrpos; 2659 } 2660 2661 /* 2662 * If there aren't alternate sectors, increment the 2663 * rotational position variables for the cbtorpos() 2664 * reimplementation. Note that we potentially 2665 * increment rpos twice. Once by rpos_incr, and one 2666 * more time when we wrap to a new track because 2667 * trackoff >= fs_nsect. 2668 */ 2669 if (!spc_flag) { 2670 trackoff += trackoff_incr; 2671 rpos += rpos_incr; 2672 if (trackoff >= sblock.fs_nsect) { 2673 trackoff -= sblock.fs_nsect; 2674 rpos++; 2675 } 2676 if (rpos >= sblock.fs_nrpos) 2677 rpos -= sblock.fs_nrpos; 2678 } 2679 } 2680 2681 if (d < dmax - cbase) { 2682 icg.cg_frsum[dmax - cbase - d]++; 2683 for (; d < dmax - cbase; d++) { 2684 setbit(cg_blksfree(&icg), d); 2685 icg.cg_cs.cs_nffree++; 2686 } 2687 } 2688 sblock.fs_cstotal.cs_ndir += icg.cg_cs.cs_ndir; 2689 sblock.fs_cstotal.cs_nffree += icg.cg_cs.cs_nffree; 2690 sblock.fs_cstotal.cs_nbfree += icg.cg_cs.cs_nbfree; 2691 sblock.fs_cstotal.cs_nifree += icg.cg_cs.cs_nifree; 2692 *cs = icg.cg_cs; 2693 awtfs(fsbtodb(&sblock, (uint64_t)cgtod(&sblock, cylno)), 2694 sblock.fs_bsize, (char *)&icg, RELEASE); 2695 } 2696 2697 /* 2698 * initialize the file system 2699 */ 2700 struct inode node; 2701 2702 #define LOSTDIR 2703 #ifdef LOSTDIR 2704 #define PREDEFDIR 3 2705 #else 2706 #define PREDEFDIR 2 2707 #endif 2708 2709 struct direct root_dir[] = { 2710 { UFSROOTINO, sizeof (struct direct), 1, "." }, 2711 { UFSROOTINO, sizeof (struct direct), 2, ".." }, 2712 #ifdef LOSTDIR 2713 { LOSTFOUNDINO, sizeof (struct direct), 10, "lost+found" }, 2714 #endif 2715 }; 2716 #ifdef LOSTDIR 2717 struct direct lost_found_dir[] = { 2718 { LOSTFOUNDINO, sizeof (struct direct), 1, "." }, 2719 { UFSROOTINO, sizeof (struct direct), 2, ".." }, 2720 { 0, DIRBLKSIZ, 0, 0 }, 2721 }; 2722 #endif 2723 char buf[MAXBSIZE]; 2724 2725 static void 2726 fsinit() 2727 { 2728 int i; 2729 2730 2731 /* 2732 * initialize the node 2733 */ 2734 node.i_atime = mkfstime; 2735 node.i_mtime = mkfstime; 2736 node.i_ctime = mkfstime; 2737 #ifdef LOSTDIR 2738 /* 2739 * create the lost+found directory 2740 */ 2741 (void) makedir(lost_found_dir, 2); 2742 for (i = DIRBLKSIZ; i < sblock.fs_bsize; i += DIRBLKSIZ) { 2743 bcopy(&lost_found_dir[2], &buf[i], DIRSIZ(&lost_found_dir[2])); 2744 } 2745 node.i_number = LOSTFOUNDINO; 2746 node.i_smode = node.i_mode = IFDIR | 0700; 2747 node.i_nlink = 2; 2748 node.i_size = sblock.fs_bsize; 2749 node.i_db[0] = alloc((int)node.i_size, node.i_mode); 2750 node.i_blocks = btodb(fragroundup(&sblock, (int)node.i_size)); 2751 IRANDOMIZE(&node.i_ic); 2752 wtfs(fsbtodb(&sblock, (uint64_t)node.i_db[0]), (int)node.i_size, buf); 2753 iput(&node); 2754 #endif 2755 /* 2756 * create the root directory 2757 */ 2758 node.i_number = UFSROOTINO; 2759 node.i_mode = node.i_smode = IFDIR | UMASK; 2760 node.i_nlink = PREDEFDIR; 2761 node.i_size = makedir(root_dir, PREDEFDIR); 2762 node.i_db[0] = alloc(sblock.fs_fsize, node.i_mode); 2763 /* i_size < 2GB because we are initializing the file system */ 2764 node.i_blocks = btodb(fragroundup(&sblock, (int)node.i_size)); 2765 IRANDOMIZE(&node.i_ic); 2766 wtfs(fsbtodb(&sblock, (uint64_t)node.i_db[0]), sblock.fs_fsize, buf); 2767 iput(&node); 2768 } 2769 2770 /* 2771 * construct a set of directory entries in "buf". 2772 * return size of directory. 2773 */ 2774 static int 2775 makedir(struct direct *protodir, int entries) 2776 { 2777 char *cp; 2778 int i; 2779 ushort_t spcleft; 2780 2781 spcleft = DIRBLKSIZ; 2782 for (cp = buf, i = 0; i < entries - 1; i++) { 2783 protodir[i].d_reclen = DIRSIZ(&protodir[i]); 2784 bcopy(&protodir[i], cp, protodir[i].d_reclen); 2785 cp += protodir[i].d_reclen; 2786 spcleft -= protodir[i].d_reclen; 2787 } 2788 protodir[i].d_reclen = spcleft; 2789 bcopy(&protodir[i], cp, DIRSIZ(&protodir[i])); 2790 return (DIRBLKSIZ); 2791 } 2792 2793 /* 2794 * allocate a block or frag 2795 */ 2796 static daddr32_t 2797 alloc(int size, int mode) 2798 { 2799 int i, frag; 2800 daddr32_t d; 2801 2802 rdfs(fsbtodb(&sblock, (uint64_t)cgtod(&sblock, 0)), sblock.fs_cgsize, 2803 (char *)&acg); 2804 if (acg.cg_magic != CG_MAGIC) { 2805 (void) fprintf(stderr, gettext("cg 0: bad magic number\n")); 2806 lockexit(32); 2807 } 2808 if (acg.cg_cs.cs_nbfree == 0) { 2809 (void) fprintf(stderr, 2810 gettext("first cylinder group ran out of space\n")); 2811 lockexit(32); 2812 } 2813 for (d = 0; d < acg.cg_ndblk; d += sblock.fs_frag) 2814 if (isblock(&sblock, cg_blksfree(&acg), d / sblock.fs_frag)) 2815 goto goth; 2816 (void) fprintf(stderr, 2817 gettext("internal error: can't find block in cyl 0\n")); 2818 lockexit(32); 2819 goth: 2820 clrblock(&sblock, cg_blksfree(&acg), d / sblock.fs_frag); 2821 acg.cg_cs.cs_nbfree--; 2822 sblock.fs_cstotal.cs_nbfree--; 2823 fscs[0].cs_nbfree--; 2824 if (mode & IFDIR) { 2825 acg.cg_cs.cs_ndir++; 2826 sblock.fs_cstotal.cs_ndir++; 2827 fscs[0].cs_ndir++; 2828 } 2829 cg_blktot(&acg)[cbtocylno(&sblock, d)]--; 2830 cg_blks(&sblock, &acg, cbtocylno(&sblock, d))[cbtorpos(&sblock, d)]--; 2831 if (size != sblock.fs_bsize) { 2832 frag = howmany(size, sblock.fs_fsize); 2833 fscs[0].cs_nffree += sblock.fs_frag - frag; 2834 sblock.fs_cstotal.cs_nffree += sblock.fs_frag - frag; 2835 acg.cg_cs.cs_nffree += sblock.fs_frag - frag; 2836 acg.cg_frsum[sblock.fs_frag - frag]++; 2837 for (i = frag; i < sblock.fs_frag; i++) 2838 setbit(cg_blksfree(&acg), d + i); 2839 } 2840 wtfs(fsbtodb(&sblock, (uint64_t)cgtod(&sblock, 0)), sblock.fs_cgsize, 2841 (char *)&acg); 2842 return (d); 2843 } 2844 2845 /* 2846 * Allocate an inode on the disk 2847 */ 2848 static void 2849 iput(struct inode *ip) 2850 { 2851 struct dinode buf[MAXINOPB]; 2852 diskaddr_t d; 2853 2854 rdfs(fsbtodb(&sblock, (uint64_t)cgtod(&sblock, 0)), sblock.fs_cgsize, 2855 (char *)&acg); 2856 if (acg.cg_magic != CG_MAGIC) { 2857 (void) fprintf(stderr, gettext("cg 0: bad magic number\n")); 2858 lockexit(32); 2859 } 2860 acg.cg_cs.cs_nifree--; 2861 setbit(cg_inosused(&acg), ip->i_number); 2862 wtfs(fsbtodb(&sblock, (uint64_t)cgtod(&sblock, 0)), sblock.fs_cgsize, 2863 (char *)&acg); 2864 sblock.fs_cstotal.cs_nifree--; 2865 fscs[0].cs_nifree--; 2866 if ((int)ip->i_number >= sblock.fs_ipg * sblock.fs_ncg) { 2867 (void) fprintf(stderr, 2868 gettext("fsinit: inode value out of range (%d).\n"), 2869 ip->i_number); 2870 lockexit(32); 2871 } 2872 d = fsbtodb(&sblock, (uint64_t)itod(&sblock, (int)ip->i_number)); 2873 rdfs(d, sblock.fs_bsize, (char *)buf); 2874 buf[itoo(&sblock, (int)ip->i_number)].di_ic = ip->i_ic; 2875 wtfs(d, sblock.fs_bsize, (char *)buf); 2876 } 2877 2878 /* 2879 * getbuf() -- Get a buffer for use in an AIO operation. Buffer 2880 * is zero'd the first time returned, left with whatever 2881 * was in memory after that. This function actually gets 2882 * enough memory the first time it's called to support 2883 * MAXBUF buffers like a slab allocator. When all the 2884 * buffers are in use, it waits for an aio to complete 2885 * and make a buffer available. 2886 * 2887 * Never returns an error. Either succeeds or exits. 2888 */ 2889 static char * 2890 getbuf(bufhdr *bufhead, int size) 2891 { 2892 bufhdr *pbuf; 2893 bufhdr *prev; 2894 int i; 2895 int buf_size, max_bufs; 2896 2897 /* 2898 * Initialize all the buffers 2899 */ 2900 if (bufhead->head == NULL) { 2901 /* 2902 * round up the size of our buffer header to a 2903 * 16 byte boundary so the address we return to 2904 * the caller is "suitably aligned". 2905 */ 2906 bufhdrsize = (sizeof (bufhdr) + 15) & ~15; 2907 2908 /* 2909 * Add in our header to the buffer and round it all up to 2910 * a 16 byte boundry so each member of the slab is aligned. 2911 */ 2912 buf_size = (size + bufhdrsize + 15) & ~15; 2913 2914 /* 2915 * Limit number of buffers to lesser of MAXBUFMEM's worth 2916 * or MAXBUF, whichever is less. 2917 */ 2918 max_bufs = MAXBUFMEM / buf_size; 2919 if (max_bufs > MAXBUF) 2920 max_bufs = MAXBUF; 2921 2922 pbuf = (bufhdr *)calloc(max_bufs, buf_size); 2923 if (pbuf == NULL) { 2924 perror("calloc"); 2925 lockexit(32); 2926 } 2927 2928 bufhead->head = bufhead; 2929 prev = bufhead; 2930 for (i = 0; i < max_bufs; i++) { 2931 pbuf->head = bufhead; 2932 prev->next = pbuf; 2933 prev = pbuf; 2934 pbuf = (bufhdr *)((char *)pbuf + buf_size); 2935 } 2936 } 2937 2938 /* 2939 * Get an available buffer, waiting for I/O if necessary 2940 */ 2941 wait_for_write(NOBLOCK); 2942 while (bufhead->next == NULL) 2943 wait_for_write(BLOCK); 2944 2945 /* 2946 * Take the buffer off the list 2947 */ 2948 pbuf = bufhead->next; 2949 bufhead->next = pbuf->next; 2950 pbuf->next = NULL; 2951 2952 /* 2953 * return the empty buffer space just past the header 2954 */ 2955 return ((char *)pbuf + bufhdrsize); 2956 } 2957 2958 /* 2959 * freebuf() -- Free a buffer gotten previously through getbuf. 2960 * Puts the buffer back on the appropriate list for 2961 * later use. Never calls free(). 2962 * 2963 * Assumes that SIGINT is blocked. 2964 */ 2965 static void 2966 freebuf(char *buf) 2967 { 2968 bufhdr *pbuf; 2969 bufhdr *bufhead; 2970 2971 /* 2972 * get the header for this buffer 2973 */ 2974 pbuf = (bufhdr *)(buf - bufhdrsize); 2975 2976 /* 2977 * Put it back on the list of available buffers 2978 */ 2979 bufhead = pbuf->head; 2980 pbuf->next = bufhead->next; 2981 bufhead->next = pbuf; 2982 } 2983 2984 /* 2985 * freetrans() -- Free a transaction gotten previously through getaiop. 2986 * Puts the transaction struct back on the appropriate list for 2987 * later use. Never calls free(). 2988 * 2989 * Assumes that SIGINT is blocked. 2990 */ 2991 static void 2992 freetrans(aio_trans *transp) 2993 { 2994 /* 2995 * free the buffer associated with this AIO if needed 2996 */ 2997 if (transp->release == RELEASE) 2998 freebuf(transp->buffer); 2999 3000 /* 3001 * Put transaction on the free list 3002 */ 3003 transp->next = results.trans; 3004 results.trans = transp; 3005 } 3006 3007 /* 3008 * wait_for_write() -- Wait for an aio write to complete. Return 3009 * the transaction structure for that write. 3010 * 3011 * Blocks SIGINT if necessary. 3012 */ 3013 aio_trans * 3014 wait_for_write(int block) 3015 { 3016 aio_trans *transp; 3017 aio_result_t *resultp; 3018 static struct timeval zero_wait = { 0, 0 }; 3019 sigset_t old_mask; 3020 3021 /* 3022 * If we know there aren't any outstanding transactions, just return 3023 */ 3024 if (results.outstanding == 0) 3025 return ((aio_trans *) 0); 3026 3027 block_sigint(&old_mask); 3028 3029 resultp = aiowait(block ? NULL : &zero_wait); 3030 if (resultp == NULL || 3031 (resultp == (aio_result_t *)-1 && errno == EINVAL)) { 3032 unblock_sigint(&old_mask); 3033 return ((aio_trans *) 0); 3034 } 3035 3036 results.outstanding--; 3037 transp = (aio_trans *)resultp; 3038 3039 if (resultp->aio_return != transp->size) { 3040 if (resultp->aio_return == -1) { 3041 /* 3042 * The aiowrite() may have failed because the 3043 * kernel didn't have enough memory to do the job. 3044 * Flush all pending writes and try a normal 3045 * write(). wtfs_breakup() will call exit if it 3046 * fails, so we don't worry about errors here. 3047 */ 3048 flush_writes(); 3049 wtfs_breakup(transp->bno, transp->size, transp->buffer); 3050 } else { 3051 (void) fprintf(stderr, gettext( 3052 "short write (%d of %d bytes) on sector %lld\n"), 3053 resultp->aio_return, transp->size, 3054 transp->bno); 3055 /* 3056 * Don't unblock SIGINT, to avoid potential 3057 * looping due to queued interrupts and 3058 * error handling. 3059 */ 3060 lockexit(32); 3061 } 3062 } 3063 3064 resultp->aio_return = 0; 3065 freetrans(transp); 3066 unblock_sigint(&old_mask); 3067 return (transp); 3068 } 3069 3070 /* 3071 * flush_writes() -- flush all the outstanding aio writes. 3072 */ 3073 static void 3074 flush_writes(void) 3075 { 3076 while (wait_for_write(BLOCK)) 3077 ; 3078 } 3079 3080 /* 3081 * get_aiop() -- find and return an aio_trans structure on which a new 3082 * aio can be done. Blocks on aiowait() if needed. Reaps 3083 * all outstanding completed aio's. 3084 * 3085 * Assumes that SIGINT is blocked. 3086 */ 3087 aio_trans * 3088 get_aiop() 3089 { 3090 int i; 3091 aio_trans *transp; 3092 aio_trans *prev; 3093 3094 /* 3095 * initialize aio stuff 3096 */ 3097 if (!aio_inited) { 3098 aio_inited = 1; 3099 3100 results.maxpend = 0; 3101 results.outstanding = 0; 3102 results.max = MAXAIO; 3103 3104 results.trans = (aio_trans *)calloc(results.max, 3105 sizeof (aio_trans)); 3106 if (results.trans == NULL) { 3107 perror("calloc"); 3108 lockexit(32); 3109 } 3110 3111 /* 3112 * Initialize the linked list of aio transaction 3113 * structures. Note that the final "next" pointer 3114 * will be NULL since we got the buffer from calloc(). 3115 */ 3116 prev = results.trans; 3117 for (i = 1; i < results.max; i++) { 3118 prev->next = &(results.trans[i]); 3119 prev = prev->next; 3120 } 3121 } 3122 3123 wait_for_write(NOBLOCK); 3124 while (results.trans == NULL) 3125 wait_for_write(BLOCK); 3126 transp = results.trans; 3127 results.trans = results.trans->next; 3128 3129 transp->next = 0; 3130 transp->resultbuf.aio_return = AIO_INPROGRESS; 3131 return (transp); 3132 } 3133 3134 /* 3135 * read a block from the file system 3136 */ 3137 static void 3138 rdfs(diskaddr_t bno, int size, char *bf) 3139 { 3140 int n, saverr; 3141 3142 /* 3143 * In case we need any data that's pending in an aiowrite(), 3144 * we wait for them all to complete before doing a read. 3145 */ 3146 flush_writes(); 3147 3148 /* 3149 * Note: the llseek() can succeed, even if the offset is out of range. 3150 * It's not until the file i/o operation (the read()) that one knows 3151 * for sure if the raw device can handle the offset. 3152 */ 3153 if (llseek(fsi, (offset_t)bno * sectorsize, 0) < 0) { 3154 saverr = errno; 3155 (void) fprintf(stderr, 3156 gettext("seek error on sector %lld: %s\n"), 3157 bno, strerror(saverr)); 3158 lockexit(32); 3159 } 3160 n = read(fsi, bf, size); 3161 if (n != size) { 3162 saverr = errno; 3163 if (n == -1) 3164 (void) fprintf(stderr, 3165 gettext("read error on sector %lld: %s\n"), 3166 bno, strerror(saverr)); 3167 else 3168 (void) fprintf(stderr, gettext( 3169 "short read (%d of %d bytes) on sector %lld\n"), 3170 n, size, bno); 3171 lockexit(32); 3172 } 3173 } 3174 3175 /* 3176 * write a block to the file system 3177 */ 3178 static void 3179 wtfs(diskaddr_t bno, int size, char *bf) 3180 { 3181 int n, saverr; 3182 3183 if (fso == -1) 3184 return; 3185 3186 /* 3187 * Note: the llseek() can succeed, even if the offset is out of range. 3188 * It's not until the file i/o operation (the write()) that one knows 3189 * for sure if the raw device can handle the offset. 3190 */ 3191 if (llseek(fso, (offset_t)bno * sectorsize, 0) < 0) { 3192 saverr = errno; 3193 (void) fprintf(stderr, 3194 gettext("seek error on sector %lld: %s\n"), 3195 bno, strerror(saverr)); 3196 lockexit(32); 3197 } 3198 if (Nflag) 3199 return; 3200 n = write(fso, bf, size); 3201 if (n != size) { 3202 saverr = errno; 3203 if (n == -1) 3204 (void) fprintf(stderr, 3205 gettext("write error on sector %lld: %s\n"), 3206 bno, strerror(saverr)); 3207 else 3208 (void) fprintf(stderr, gettext( 3209 "short write (%d of %d bytes) on sector %lld\n"), 3210 n, size, bno); 3211 lockexit(32); 3212 } 3213 } 3214 3215 /* 3216 * write a block to the file system -- buffered with aio 3217 */ 3218 static void 3219 awtfs(diskaddr_t bno, int size, char *bf, int release) 3220 { 3221 int n; 3222 aio_trans *transp; 3223 sigset_t old_mask; 3224 3225 if (fso == -1) 3226 return; 3227 3228 /* 3229 * We need to keep things consistent if we get interrupted, 3230 * so defer any expected interrupts for the time being. 3231 */ 3232 block_sigint(&old_mask); 3233 3234 if (Nflag) { 3235 if (release == RELEASE) 3236 freebuf(bf); 3237 } else { 3238 transp = get_aiop(); 3239 transp->bno = bno; 3240 transp->buffer = bf; 3241 transp->size = size; 3242 transp->release = release; 3243 3244 n = aiowrite(fso, bf, size, (off_t)bno * sectorsize, 3245 SEEK_SET, &transp->resultbuf); 3246 3247 if (n < 0) { 3248 /* 3249 * The aiowrite() may have failed because the 3250 * kernel didn't have enough memory to do the job. 3251 * Flush all pending writes and try a normal 3252 * write(). wtfs_breakup() will call exit if it 3253 * fails, so we don't worry about errors here. 3254 */ 3255 flush_writes(); 3256 wtfs_breakup(transp->bno, transp->size, transp->buffer); 3257 freetrans(transp); 3258 } else { 3259 /* 3260 * Keep track of our pending writes. 3261 */ 3262 results.outstanding++; 3263 if (results.outstanding > results.maxpend) 3264 results.maxpend = results.outstanding; 3265 } 3266 } 3267 3268 unblock_sigint(&old_mask); 3269 } 3270 3271 3272 /* 3273 * write a block to the file system, but break it up into sbsize 3274 * chunks to avoid forcing a large amount of memory to be locked down. 3275 * Only used as a fallback when an aio write has failed. 3276 */ 3277 static void 3278 wtfs_breakup(diskaddr_t bno, int size, char *bf) 3279 { 3280 int n, saverr; 3281 int wsize; 3282 int block_incr = sbsize / sectorsize; 3283 3284 if (size < sbsize) 3285 wsize = size; 3286 else 3287 wsize = sbsize; 3288 3289 n = 0; 3290 while (size) { 3291 /* 3292 * Note: the llseek() can succeed, even if the offset is 3293 * out of range. It's not until the file i/o operation 3294 * (the write()) that one knows for sure if the raw device 3295 * can handle the offset. 3296 */ 3297 if (llseek(fso, (offset_t)bno * sectorsize, 0) < 0) { 3298 saverr = errno; 3299 (void) fprintf(stderr, 3300 gettext("seek error on sector %lld: %s\n"), 3301 bno, strerror(saverr)); 3302 lockexit(32); 3303 } 3304 3305 n = write(fso, bf, wsize); 3306 if (n == -1) { 3307 saverr = errno; 3308 (void) fprintf(stderr, 3309 gettext("write error on sector %lld: %s\n"), 3310 bno, strerror(saverr)); 3311 lockexit(32); 3312 } 3313 if (n != wsize) { 3314 saverr = errno; 3315 (void) fprintf(stderr, gettext( 3316 "short write (%d of %d bytes) on sector %lld\n"), 3317 n, size, bno); 3318 lockexit(32); 3319 } 3320 3321 bno += block_incr; 3322 bf += wsize; 3323 size -= wsize; 3324 if (size < wsize) 3325 wsize = size; 3326 } 3327 } 3328 3329 3330 /* 3331 * check if a block is available 3332 */ 3333 static int 3334 isblock(struct fs *fs, unsigned char *cp, int h) 3335 { 3336 unsigned char mask; 3337 3338 switch (fs->fs_frag) { 3339 case 8: 3340 return (cp[h] == 0xff); 3341 case 4: 3342 mask = 0x0f << ((h & 0x1) << 2); 3343 return ((cp[h >> 1] & mask) == mask); 3344 case 2: 3345 mask = 0x03 << ((h & 0x3) << 1); 3346 return ((cp[h >> 2] & mask) == mask); 3347 case 1: 3348 mask = 0x01 << (h & 0x7); 3349 return ((cp[h >> 3] & mask) == mask); 3350 default: 3351 (void) fprintf(stderr, "isblock bad fs_frag %d\n", fs->fs_frag); 3352 return (0); 3353 } 3354 } 3355 3356 /* 3357 * take a block out of the map 3358 */ 3359 static void 3360 clrblock(struct fs *fs, unsigned char *cp, int h) 3361 { 3362 switch ((fs)->fs_frag) { 3363 case 8: 3364 cp[h] = 0; 3365 return; 3366 case 4: 3367 cp[h >> 1] &= ~(0x0f << ((h & 0x1) << 2)); 3368 return; 3369 case 2: 3370 cp[h >> 2] &= ~(0x03 << ((h & 0x3) << 1)); 3371 return; 3372 case 1: 3373 cp[h >> 3] &= ~(0x01 << (h & 0x7)); 3374 return; 3375 default: 3376 (void) fprintf(stderr, 3377 gettext("clrblock: bad fs_frag value %d\n"), fs->fs_frag); 3378 return; 3379 } 3380 } 3381 3382 /* 3383 * put a block into the map 3384 */ 3385 static void 3386 setblock(struct fs *fs, unsigned char *cp, int h) 3387 { 3388 switch (fs->fs_frag) { 3389 case 8: 3390 cp[h] = 0xff; 3391 return; 3392 case 4: 3393 cp[h >> 1] |= (0x0f << ((h & 0x1) << 2)); 3394 return; 3395 case 2: 3396 cp[h >> 2] |= (0x03 << ((h & 0x3) << 1)); 3397 return; 3398 case 1: 3399 cp[h >> 3] |= (0x01 << (h & 0x7)); 3400 return; 3401 default: 3402 (void) fprintf(stderr, 3403 gettext("setblock: bad fs_frag value %d\n"), fs->fs_frag); 3404 return; 3405 } 3406 } 3407 3408 static void 3409 usage() 3410 { 3411 (void) fprintf(stderr, 3412 gettext("ufs usage: mkfs [-F FSType] [-V] [-m] [-o options] " 3413 "special " /* param 0 */ 3414 "size(sectors) \\ \n")); /* param 1 */ 3415 (void) fprintf(stderr, 3416 "[nsect " /* param 2 */ 3417 "ntrack " /* param 3 */ 3418 "bsize " /* param 4 */ 3419 "fragsize " /* param 5 */ 3420 "cpg " /* param 6 */ 3421 "free " /* param 7 */ 3422 "rps " /* param 8 */ 3423 "nbpi " /* param 9 */ 3424 "opt " /* param 10 */ 3425 "apc " /* param 11 */ 3426 "gap " /* param 12 */ 3427 "nrpos " /* param 13 */ 3428 "maxcontig " /* param 14 */ 3429 "mtb]\n"); /* param 15 */ 3430 (void) fprintf(stderr, 3431 gettext(" -m : dump fs cmd line used to make this partition\n" 3432 " -V :print this command line and return\n" 3433 " -o :ufs options: :nsect=%d,ntrack=%d,bsize=%d,fragsize=%d\n" 3434 " -o :ufs options: :cgsize=%d,free=%d,rps=%d,nbpi=%d,opt=%c\n" 3435 " -o :ufs options: :apc=%d,gap=%d,nrpos=%d,maxcontig=%d\n" 3436 " -o :ufs options: :mtb=%c,calcsb,calcbinsb\n" 3437 "NOTE that all -o suboptions: must be separated only by commas so as to\n" 3438 "be parsed as a single argument\n"), 3439 nsect, ntrack, bsize, fragsize, cpg, sblock.fs_minfree, rps, 3440 nbpi, opt, apc, (rotdelay == -1) ? 0 : rotdelay, 3441 sblock.fs_nrpos, maxcontig, mtb); 3442 lockexit(32); 3443 } 3444 3445 /*ARGSUSED*/ 3446 static void 3447 dump_fscmd(char *fsys, int fsi) 3448 { 3449 int64_t used, bpcg, inospercg; 3450 int64_t nbpi; 3451 uint64_t nbytes64; 3452 3453 bzero((char *)&sblock, sizeof (sblock)); 3454 rdfs((diskaddr_t)SBLOCK, SBSIZE, (char *)&sblock); 3455 3456 /* 3457 * ensure a valid file system and if not, exit with error or else 3458 * we will end up computing block numbers etc and dividing by zero 3459 * which will cause floating point errors in this routine. 3460 */ 3461 3462 if ((sblock.fs_magic != FS_MAGIC) && 3463 (sblock.fs_magic != MTB_UFS_MAGIC)) { 3464 (void) fprintf(stderr, gettext( 3465 "[not currently a valid file system - bad superblock]\n")); 3466 lockexit(32); 3467 } 3468 3469 if (sblock.fs_magic == FS_MAGIC && 3470 (sblock.fs_version != UFS_EFISTYLE4NONEFI_VERSION_2 && 3471 sblock.fs_version != UFS_VERSION_MIN)) { 3472 (void) fprintf(stderr, gettext( 3473 "Unknown version of UFS format: %d\n"), sblock.fs_version); 3474 lockexit(32); 3475 } 3476 3477 if (sblock.fs_magic == MTB_UFS_MAGIC && 3478 (sblock.fs_version > MTB_UFS_VERSION_1 || 3479 sblock.fs_version < MTB_UFS_VERSION_MIN)) { 3480 (void) fprintf(stderr, gettext( 3481 "Unknown version of UFS format: %d\n"), sblock.fs_version); 3482 lockexit(32); 3483 } 3484 3485 /* 3486 * Compute a reasonable nbpi value. 3487 * The algorithm for "used" is copied from code 3488 * in main() verbatim. 3489 * The nbpi equation is taken from main where the 3490 * fs_ipg value is set for the last time. The INOPB(...) - 1 3491 * is used to account for the roundup. 3492 * The problem is that a range of nbpi values map to 3493 * the same file system layout. So it is not possible 3494 * to calculate the exact value specified when the file 3495 * system was created. So instead we determine the top 3496 * end of the range of values. 3497 */ 3498 bpcg = sblock.fs_spc * sectorsize; 3499 inospercg = (int64_t)roundup(bpcg / sizeof (struct dinode), 3500 INOPB(&sblock)); 3501 if (inospercg > MAXIpG(&sblock)) 3502 inospercg = MAXIpG(&sblock); 3503 used = (int64_t) 3504 (sblock.fs_iblkno + inospercg / INOPF(&sblock)) * NSPF(&sblock); 3505 used *= sectorsize; 3506 nbytes64 = (uint64_t)sblock.fs_cpg * bpcg - used; 3507 3508 /* 3509 * The top end of the range of values for nbpi may not be 3510 * a valid command line value for mkfs. Report the bottom 3511 * end instead. 3512 */ 3513 nbpi = (int64_t)(nbytes64 / (sblock.fs_ipg)); 3514 3515 (void) fprintf(stdout, gettext("mkfs -F ufs -o "), fsys); 3516 (void) fprintf(stdout, "nsect=%d,ntrack=%d,", 3517 sblock.fs_nsect, sblock.fs_ntrak); 3518 (void) fprintf(stdout, "bsize=%d,fragsize=%d,cgsize=%d,free=%d,", 3519 sblock.fs_bsize, sblock.fs_fsize, sblock.fs_cpg, sblock.fs_minfree); 3520 (void) fprintf(stdout, "rps=%d,nbpi=%lld,opt=%c,apc=%d,gap=%d,", 3521 sblock.fs_rps, nbpi, (sblock.fs_optim == FS_OPTSPACE) ? 's' : 't', 3522 (sblock.fs_ntrak * sblock.fs_nsect) - sblock.fs_spc, 3523 sblock.fs_rotdelay); 3524 (void) fprintf(stdout, "nrpos=%d,maxcontig=%d,mtb=%c ", 3525 sblock.fs_nrpos, sblock.fs_maxcontig, 3526 ((sblock.fs_magic == MTB_UFS_MAGIC) ? 'y' : 'n')); 3527 (void) fprintf(stdout, "%s %lld\n", fsys, 3528 fsbtodb(&sblock, sblock.fs_size)); 3529 3530 bzero((char *)&sblock, sizeof (sblock)); 3531 } 3532 3533 /* number ************************************************************* */ 3534 /* */ 3535 /* Convert a numeric string arg to binary */ 3536 /* */ 3537 /* Args: d_value - default value, if have parse error */ 3538 /* param - the name of the argument, for error messages */ 3539 /* flags - parser state and what's allowed in the arg */ 3540 /* Global arg: string - pointer to command arg */ 3541 /* */ 3542 /* Valid forms: 123 | 123k | 123*123 | 123x123 */ 3543 /* */ 3544 /* Return: converted number */ 3545 /* */ 3546 /* ******************************************************************** */ 3547 3548 static uint64_t 3549 number(uint64_t d_value, char *param, int flags) 3550 { 3551 char *cs; 3552 uint64_t n, t; 3553 uint64_t cut = BIG / 10; /* limit to avoid overflow */ 3554 int minus = 0; 3555 3556 cs = string; 3557 if (*cs == '-') { 3558 minus = 1; 3559 cs += 1; 3560 } 3561 if ((*cs < '0') || (*cs > '9')) { 3562 goto bail_out; 3563 } 3564 n = 0; 3565 while ((*cs >= '0') && (*cs <= '9') && (n <= cut)) { 3566 n = n*10 + *cs++ - '0'; 3567 } 3568 if (minus) 3569 n = -n; 3570 for (;;) { 3571 switch (*cs++) { 3572 case 'k': 3573 if (flags & ALLOW_END_ONLY) 3574 goto bail_out; 3575 if (n > (BIG / 1024)) 3576 goto overflow; 3577 n *= 1024; 3578 continue; 3579 3580 case '*': 3581 case 'x': 3582 if (flags & ALLOW_END_ONLY) 3583 goto bail_out; 3584 string = cs; 3585 t = number(d_value, param, flags); 3586 if (n > (BIG / t)) 3587 goto overflow; 3588 n *= t; 3589 cs = string + 1; /* adjust for -- below */ 3590 3591 /* recursion has read rest of expression */ 3592 /* FALLTHROUGH */ 3593 3594 case ',': 3595 case '\0': 3596 cs--; 3597 string = cs; 3598 return (n); 3599 3600 case '%': 3601 if (flags & ALLOW_END_ONLY) 3602 goto bail_out; 3603 if (flags & ALLOW_PERCENT) { 3604 flags &= ~ALLOW_PERCENT; 3605 flags |= ALLOW_END_ONLY; 3606 continue; 3607 } 3608 goto bail_out; 3609 3610 case 'm': 3611 if (flags & ALLOW_END_ONLY) 3612 goto bail_out; 3613 if (flags & ALLOW_MS1) { 3614 flags &= ~ALLOW_MS1; 3615 flags |= ALLOW_MS2; 3616 continue; 3617 } 3618 goto bail_out; 3619 3620 case 's': 3621 if (flags & ALLOW_END_ONLY) 3622 goto bail_out; 3623 if (flags & ALLOW_MS2) { 3624 flags &= ~ALLOW_MS2; 3625 flags |= ALLOW_END_ONLY; 3626 continue; 3627 } 3628 goto bail_out; 3629 3630 case '0': case '1': case '2': case '3': case '4': 3631 case '5': case '6': case '7': case '8': case '9': 3632 overflow: 3633 (void) fprintf(stderr, 3634 gettext("mkfs: value for %s overflowed\n"), 3635 param); 3636 while ((*cs != '\0') && (*cs != ',')) 3637 cs++; 3638 string = cs; 3639 return (BIG); 3640 3641 default: 3642 bail_out: 3643 (void) fprintf(stderr, gettext( 3644 "mkfs: bad numeric arg for %s: \"%s\"\n"), 3645 param, string); 3646 while ((*cs != '\0') && (*cs != ',')) 3647 cs++; 3648 string = cs; 3649 if (d_value != NO_DEFAULT) { 3650 (void) fprintf(stderr, 3651 gettext("mkfs: %s reset to default %lld\n"), 3652 param, d_value); 3653 return (d_value); 3654 } 3655 lockexit(2); 3656 3657 } 3658 } /* never gets here */ 3659 } 3660 3661 /* match ************************************************************** */ 3662 /* */ 3663 /* Compare two text strings for equality */ 3664 /* */ 3665 /* Arg: s - pointer to string to match with a command arg */ 3666 /* Global arg: string - pointer to command arg */ 3667 /* */ 3668 /* Return: 1 if match, 0 if no match */ 3669 /* If match, also reset `string' to point to the text */ 3670 /* that follows the matching text. */ 3671 /* */ 3672 /* ******************************************************************** */ 3673 3674 static int 3675 match(char *s) 3676 { 3677 char *cs; 3678 3679 cs = string; 3680 while (*cs++ == *s) { 3681 if (*s++ == '\0') { 3682 goto true; 3683 } 3684 } 3685 if (*s != '\0') { 3686 return (0); 3687 } 3688 3689 true: 3690 cs--; 3691 string = cs; 3692 return (1); 3693 } 3694 3695 /* 3696 * GROWFS ROUTINES 3697 */ 3698 3699 /* ARGSUSED */ 3700 void 3701 lockexit(int exitstatus) 3702 { 3703 if (Pflag) { 3704 /* the probe mode neither changes nor locks the filesystem */ 3705 exit(exitstatus); 3706 } 3707 3708 /* 3709 * flush the dirty cylinder group 3710 */ 3711 if (inlockexit == 0) { 3712 inlockexit = 1; 3713 flcg(); 3714 } 3715 3716 if (aio_inited) { 3717 flush_writes(); 3718 } 3719 3720 /* 3721 * make sure the file system is unlocked before exiting 3722 */ 3723 if ((inlockexit == 1) && (!isbad)) { 3724 inlockexit = 2; 3725 ulockfs(); 3726 /* 3727 * if logging was enabled, then re-enable it 3728 */ 3729 if (waslog) { 3730 if (rl_log_control(fsys, _FIOLOGENABLE) != RL_SUCCESS) { 3731 (void) fprintf(stderr, gettext( 3732 "failed to re-enable logging\n")); 3733 } 3734 } 3735 } else if (grow) { 3736 if (isbad) { 3737 (void) fprintf(stderr, gettext( 3738 "Filesystem is currently inconsistent. It " 3739 "must be repaired with fsck(1M)\nbefore being " 3740 "used. Use the following command to " 3741 "do this:\n\n\tfsck %s\n\n"), 3742 fsys); 3743 3744 if (ismounted) { 3745 (void) fprintf(stderr, gettext( 3746 "You will be told that the filesystem " 3747 "is already mounted, and asked if you\n" 3748 "wish to continue. Answer `yes' to " 3749 "this question.\n\n")); 3750 } 3751 3752 (void) fprintf(stderr, gettext( 3753 "One problem should be reported, that " 3754 "the summary information is bad.\n" 3755 "You will then be asked if it " 3756 "should be salvaged. Answer `yes' " 3757 "to\nthis question.\n\n")); 3758 } 3759 3760 if (ismounted) { 3761 /* 3762 * In theory, there's no way to get here without 3763 * isbad also being set, but be robust in the 3764 * face of future code changes. 3765 */ 3766 (void) fprintf(stderr, gettext( 3767 "The filesystem is currently mounted " 3768 "read-only and write-locked. ")); 3769 if (isbad) { 3770 (void) fprintf(stderr, gettext( 3771 "After\nrunning fsck, unlock the " 3772 "filesystem and ")); 3773 } else { 3774 (void) fprintf(stderr, gettext( 3775 "Unlock the filesystem\nand ")); 3776 } 3777 3778 (void) fprintf(stderr, gettext( 3779 "re-enable writing with\nthe following " 3780 "command:\n\n\tlockfs -u %s\n\n"), 3781 directory); 3782 } 3783 } 3784 3785 exit(exitstatus); 3786 } 3787 3788 void 3789 randomgeneration() 3790 { 3791 int i; 3792 struct dinode *dp; 3793 3794 /* 3795 * always perform fsirand(1) function... newfs will notice that 3796 * the inodes have been randomized and will not call fsirand itself 3797 */ 3798 for (i = 0, dp = zino; i < sblock.fs_inopb; ++i, ++dp) 3799 IRANDOMIZE(&dp->di_ic); 3800 } 3801 3802 /* 3803 * Check the size of the summary information. 3804 * Fields in sblock are not changed in this function. 3805 * 3806 * For an 8K filesystem block, the maximum number of cylinder groups is 16384. 3807 * MAXCSBUFS {32} * 8K {FS block size} 3808 * divided by (sizeof csum) {16} 3809 * 3810 * Note that MAXCSBUFS is not used in the kernel; as of Solaris 2.6 build 32, 3811 * this is the only place where it's referenced. 3812 */ 3813 void 3814 checksummarysize() 3815 { 3816 diskaddr_t dmax; 3817 diskaddr_t dmin; 3818 int64_t cg0frags; 3819 int64_t cg0blocks; 3820 int64_t maxncg; 3821 int64_t maxfrags; 3822 uint64_t fs_size; 3823 uint64_t maxfs_blocks; /* filesystem blocks for max filesystem size */ 3824 3825 /* 3826 * compute the maximum summary info size 3827 */ 3828 dmin = cgdmin(&sblock, 0); 3829 dmax = cgbase(&sblock, 0) + sblock.fs_fpg; 3830 fs_size = (grow) ? grow_fs_size : sblock.fs_size; 3831 if (dmax > fs_size) 3832 dmax = fs_size; 3833 cg0frags = dmax - dmin; 3834 cg0blocks = cg0frags / sblock.fs_frag; 3835 cg0frags = cg0blocks * sblock.fs_frag; 3836 maxncg = (longlong_t)cg0blocks * 3837 (longlong_t)(sblock.fs_bsize / sizeof (struct csum)); 3838 3839 maxfs_blocks = FS_MAX; 3840 3841 if (maxncg > ((longlong_t)maxfs_blocks / (longlong_t)sblock.fs_fpg) + 1) 3842 maxncg = ((longlong_t)maxfs_blocks / 3843 (longlong_t)sblock.fs_fpg) + 1; 3844 3845 maxfrags = maxncg * (longlong_t)sblock.fs_fpg; 3846 3847 if (maxfrags > maxfs_blocks) 3848 maxfrags = maxfs_blocks; 3849 3850 3851 /* 3852 * remember for later processing in extendsummaryinfo() 3853 */ 3854 if (test) 3855 grow_sifrag = dmin + (cg0blocks * sblock.fs_frag); 3856 if (testfrags == 0) 3857 testfrags = cg0frags; 3858 if (testforce) 3859 if (testfrags > cg0frags) { 3860 (void) fprintf(stderr, 3861 gettext("Too many test frags (%lld); " 3862 "try %lld\n"), testfrags, cg0frags); 3863 lockexit(32); 3864 } 3865 3866 /* 3867 * if summary info is too large (too many cg's) tell the user and exit 3868 */ 3869 if ((longlong_t)sblock.fs_size > maxfrags) { 3870 (void) fprintf(stderr, gettext( 3871 "Too many cylinder groups with %llu sectors;\n try " 3872 "increasing cgsize, or decreasing fssize to %llu\n"), 3873 fsbtodb(&sblock, (uint64_t)sblock.fs_size), 3874 fsbtodb(&sblock, (uint64_t)maxfrags)); 3875 lockexit(32); 3876 } 3877 } 3878 3879 /* 3880 * checksblock() has two uses: 3881 * - One is to sanity test the superblock and is used when newfs(1M) 3882 * is invoked with the "-N" option. If any discrepancy was found, 3883 * just return whatever error was found and do not exit. 3884 * - the other use of it is in places where you expect the superblock 3885 * to be sane, and if it isn't, then we exit. 3886 * Which of the above two actions to take is indicated with the second argument. 3887 */ 3888 3889 int 3890 checksblock(struct fs sb, int proceed) 3891 { 3892 int err = 0; 3893 char *errmsg; 3894 3895 if ((sb.fs_magic != FS_MAGIC) && (sb.fs_magic != MTB_UFS_MAGIC)) { 3896 err = 1; 3897 errmsg = gettext("Bad superblock; magic number wrong\n"); 3898 } else if ((sb.fs_magic == FS_MAGIC && 3899 (sb.fs_version != UFS_EFISTYLE4NONEFI_VERSION_2 && 3900 sb.fs_version != UFS_VERSION_MIN)) || 3901 (sb.fs_magic == MTB_UFS_MAGIC && 3902 (sb.fs_version > MTB_UFS_VERSION_1 || 3903 sb.fs_version < MTB_UFS_VERSION_MIN))) { 3904 err = 2; 3905 errmsg = gettext("Unrecognized version of UFS\n"); 3906 } else if (sb.fs_ncg < 1) { 3907 err = 3; 3908 errmsg = gettext("Bad superblock; ncg out of range\n"); 3909 } else if (sb.fs_cpg < 1) { 3910 err = 4; 3911 errmsg = gettext("Bad superblock; cpg out of range\n"); 3912 } else if (sb.fs_ncg * sb.fs_cpg < sb.fs_ncyl || 3913 (sb.fs_ncg - 1) * sb.fs_cpg >= sb.fs_ncyl) { 3914 err = 5; 3915 errmsg = gettext("Bad superblock; ncyl out of range\n"); 3916 } else if (sb.fs_sbsize <= 0 || sb.fs_sbsize > sb.fs_bsize) { 3917 err = 6; 3918 errmsg = gettext("Bad superblock; superblock size out of range\n"); 3919 } 3920 3921 if (proceed) { 3922 if (err) dprintf(("%s", errmsg)); 3923 return (err); 3924 } 3925 3926 if (err) { 3927 fprintf(stderr, "%s", errmsg); 3928 lockexit(32); 3929 } 3930 return (32); 3931 } 3932 3933 /* 3934 * Roll the embedded log, if any, and set up the global variables 3935 * islog, islogok and isufslog. 3936 */ 3937 static void 3938 logsetup(char *devstr) 3939 { 3940 void *buf, *ud_buf; 3941 extent_block_t *ebp; 3942 ml_unit_t *ul; 3943 ml_odunit_t *ud; 3944 3945 /* 3946 * Does the superblock indicate that we are supposed to have a log ? 3947 */ 3948 if (sblock.fs_logbno == 0) { 3949 /* 3950 * No log present, nothing to do. 3951 */ 3952 islogok = 0; 3953 islog = 0; 3954 isufslog = 0; 3955 return; 3956 } else { 3957 /* 3958 * There's a log in a yet unknown state, attempt to roll it. 3959 */ 3960 islog = 1; 3961 islogok = 0; 3962 isufslog = 0; 3963 3964 /* 3965 * We failed to roll the log, bail out. 3966 */ 3967 if (rl_roll_log(devstr) != RL_SUCCESS) 3968 return; 3969 3970 isufslog = 1; 3971 3972 /* log is not okay; check the fs */ 3973 if ((FSOKAY != (sblock.fs_state + sblock.fs_time)) || 3974 (sblock.fs_clean != FSLOG)) 3975 return; 3976 3977 /* get the log allocation block */ 3978 buf = (void *)malloc(DEV_BSIZE); 3979 if (buf == (void *) NULL) 3980 return; 3981 3982 ud_buf = (void *)malloc(DEV_BSIZE); 3983 if (ud_buf == (void *) NULL) { 3984 free(buf); 3985 return; 3986 } 3987 3988 rdfs((diskaddr_t)logbtodb(&sblock, sblock.fs_logbno), 3989 DEV_BSIZE, buf); 3990 ebp = (extent_block_t *)buf; 3991 3992 /* log allocation block is not okay; check the fs */ 3993 if (ebp->type != LUFS_EXTENTS) { 3994 free(buf); 3995 free(ud_buf); 3996 return; 3997 } 3998 3999 /* get the log state block(s) */ 4000 rdfs((diskaddr_t)logbtodb(&sblock, ebp->extents[0].pbno), 4001 DEV_BSIZE, ud_buf); 4002 ud = (ml_odunit_t *)ud_buf; 4003 ul = (ml_unit_t *)malloc(sizeof (*ul)); 4004 ul->un_ondisk = *ud; 4005 4006 /* log state is okay */ 4007 if ((ul->un_chksum == ul->un_head_ident + ul->un_tail_ident) && 4008 (ul->un_version == LUFS_VERSION_LATEST) && 4009 (ul->un_badlog == 0)) 4010 islogok = 1; 4011 free(ud_buf); 4012 free(buf); 4013 free(ul); 4014 } 4015 } 4016 4017 void 4018 growinit(char *devstr) 4019 { 4020 int i; 4021 char buf[DEV_BSIZE]; 4022 4023 /* 4024 * Read and verify the superblock 4025 */ 4026 rdfs((diskaddr_t)(SBOFF / sectorsize), (int)sbsize, (char *)&sblock); 4027 (void) checksblock(sblock, 0); 4028 if (sblock.fs_postblformat != FS_DYNAMICPOSTBLFMT) { 4029 (void) fprintf(stderr, 4030 gettext("old file system format; can't growfs\n")); 4031 lockexit(32); 4032 } 4033 4034 /* 4035 * can't shrink a file system 4036 */ 4037 grow_fssize = fsbtodb(&sblock, (uint64_t)sblock.fs_size); 4038 if (fssize_db < grow_fssize) { 4039 (void) fprintf(stderr, 4040 gettext("%lld sectors < current size of %lld sectors\n"), 4041 fssize_db, grow_fssize); 4042 lockexit(32); 4043 } 4044 4045 /* 4046 * can't grow a system to over a terabyte unless it was set up 4047 * as an MTB UFS file system. 4048 */ 4049 if (mtb == 'y' && sblock.fs_magic != MTB_UFS_MAGIC) { 4050 if (fssize_db >= SECTORS_PER_TERABYTE) { 4051 (void) fprintf(stderr, gettext( 4052 "File system was not set up with the multi-terabyte format.\n")); 4053 (void) fprintf(stderr, gettext( 4054 "Its size cannot be increased to a terabyte or more.\n")); 4055 } else { 4056 (void) fprintf(stderr, gettext( 4057 "Cannot convert file system to multi-terabyte format.\n")); 4058 } 4059 lockexit(32); 4060 } 4061 4062 logsetup(devstr); 4063 4064 /* 4065 * can't growfs when logging device has errors 4066 */ 4067 if ((islog && !islogok) || 4068 ((FSOKAY == (sblock.fs_state + sblock.fs_time)) && 4069 (sblock.fs_clean == FSLOG && !islog))) { 4070 (void) fprintf(stderr, 4071 gettext("logging device has errors; can't growfs\n")); 4072 lockexit(32); 4073 } 4074 4075 /* 4076 * disable ufs logging for growing 4077 */ 4078 if (isufslog) { 4079 if (rl_log_control(devstr, _FIOLOGDISABLE) != RL_SUCCESS) { 4080 (void) fprintf(stderr, gettext( 4081 "failed to disable logging\n")); 4082 lockexit(32); 4083 } 4084 islog = 0; 4085 waslog = 1; 4086 } 4087 4088 /* 4089 * if mounted write lock the file system to be grown 4090 */ 4091 if (ismounted) 4092 wlockfs(); 4093 4094 /* 4095 * refresh dynamic superblock state - disabling logging will have 4096 * changed the amount of free space available in the file system 4097 */ 4098 rdfs((diskaddr_t)(SBOFF / sectorsize), sbsize, (char *)&sblock); 4099 4100 /* 4101 * make sure device is big enough 4102 */ 4103 rdfs((diskaddr_t)fssize_db - 1, DEV_BSIZE, buf); 4104 wtfs((diskaddr_t)fssize_db - 1, DEV_BSIZE, buf); 4105 4106 /* 4107 * read current summary information 4108 */ 4109 grow_fscs = read_summaryinfo(&sblock); 4110 4111 /* 4112 * save some current size related fields from the superblock 4113 * These are used in extendsummaryinfo() 4114 */ 4115 grow_fs_size = sblock.fs_size; 4116 grow_fs_ncg = sblock.fs_ncg; 4117 grow_fs_csaddr = (diskaddr_t)sblock.fs_csaddr; 4118 grow_fs_cssize = sblock.fs_cssize; 4119 4120 /* 4121 * save and reset the clean flag 4122 */ 4123 if (FSOKAY == (sblock.fs_state + sblock.fs_time)) 4124 grow_fs_clean = sblock.fs_clean; 4125 else 4126 grow_fs_clean = FSBAD; 4127 sblock.fs_clean = FSBAD; 4128 sblock.fs_state = FSOKAY - sblock.fs_time; 4129 isbad = 1; 4130 wtfs((diskaddr_t)(SBOFF / sectorsize), sbsize, (char *)&sblock); 4131 } 4132 4133 void 4134 checkdev(char *rdev, char *bdev) 4135 { 4136 struct stat64 statarea; 4137 4138 if (stat64(bdev, &statarea) < 0) { 4139 (void) fprintf(stderr, gettext("can't check mount point; ")); 4140 (void) fprintf(stderr, gettext("can't stat %s\n"), bdev); 4141 lockexit(32); 4142 } 4143 if ((statarea.st_mode & S_IFMT) != S_IFBLK) { 4144 (void) fprintf(stderr, gettext( 4145 "can't check mount point; %s is not a block device\n"), 4146 bdev); 4147 lockexit(32); 4148 } 4149 if (stat64(rdev, &statarea) < 0) { 4150 (void) fprintf(stderr, gettext("can't stat %s\n"), rdev); 4151 lockexit(32); 4152 } 4153 if ((statarea.st_mode & S_IFMT) != S_IFCHR) { 4154 (void) fprintf(stderr, 4155 gettext("%s is not a character device\n"), rdev); 4156 lockexit(32); 4157 } 4158 } 4159 4160 void 4161 checkmount(struct mnttab *mntp, char *bdevname) 4162 { 4163 struct stat64 statdir; 4164 struct stat64 statdev; 4165 4166 if (strcmp(bdevname, mntp->mnt_special) == 0) { 4167 if (stat64(mntp->mnt_mountp, &statdir) == -1) { 4168 (void) fprintf(stderr, gettext("can't stat %s\n"), 4169 mntp->mnt_mountp); 4170 lockexit(32); 4171 } 4172 if (stat64(mntp->mnt_special, &statdev) == -1) { 4173 (void) fprintf(stderr, gettext("can't stat %s\n"), 4174 mntp->mnt_special); 4175 lockexit(32); 4176 } 4177 if (statdir.st_dev != statdev.st_rdev) { 4178 (void) fprintf(stderr, gettext( 4179 "%s is not mounted on %s; mnttab(4) wrong\n"), 4180 mntp->mnt_special, mntp->mnt_mountp); 4181 lockexit(32); 4182 } 4183 ismounted = 1; 4184 if (directory) { 4185 if (strcmp(mntp->mnt_mountp, directory) != 0) { 4186 (void) fprintf(stderr, 4187 gettext("%s is mounted on %s, not %s\n"), 4188 bdevname, mntp->mnt_mountp, directory); 4189 lockexit(32); 4190 } 4191 } else { 4192 if (grow) 4193 (void) fprintf(stderr, gettext( 4194 "%s is mounted on %s; can't growfs\n"), 4195 bdevname, mntp->mnt_mountp); 4196 else 4197 (void) fprintf(stderr, 4198 gettext("%s is mounted, can't mkfs\n"), 4199 bdevname); 4200 lockexit(32); 4201 } 4202 } 4203 } 4204 4205 struct dinode *dibuf = 0; 4206 diskaddr_t difrag = 0; 4207 4208 struct dinode * 4209 gdinode(ino_t ino) 4210 { 4211 /* 4212 * read the block of inodes containing inode number ino 4213 */ 4214 if (dibuf == 0) 4215 dibuf = (struct dinode *)malloc((unsigned)sblock.fs_bsize); 4216 if (itod(&sblock, ino) != difrag) { 4217 difrag = itod(&sblock, ino); 4218 rdfs(fsbtodb(&sblock, (uint64_t)difrag), (int)sblock.fs_bsize, 4219 (char *)dibuf); 4220 } 4221 return (dibuf + (ino % INOPB(&sblock))); 4222 } 4223 4224 /* 4225 * structure that manages the frags we need for extended summary info 4226 * These frags can be: 4227 * free 4228 * data block 4229 * alloc block 4230 */ 4231 struct csfrag { 4232 struct csfrag *next; /* next entry */ 4233 daddr32_t ofrag; /* old frag */ 4234 daddr32_t nfrag; /* new frag */ 4235 long cylno; /* cylno of nfrag */ 4236 long frags; /* number of frags */ 4237 long size; /* size in bytes */ 4238 ino_t ino; /* inode number */ 4239 long fixed; /* Boolean - Already fixed? */ 4240 }; 4241 struct csfrag *csfrag; /* state unknown */ 4242 struct csfrag *csfragino; /* frags belonging to an inode */ 4243 struct csfrag *csfragfree; /* frags that are free */ 4244 4245 daddr32_t maxcsfrag = 0; /* maximum in range */ 4246 daddr32_t mincsfrag = 0x7fffffff; /* minimum in range */ 4247 4248 int 4249 csfraginrange(daddr32_t frag) 4250 { 4251 return ((frag >= mincsfrag) && (frag <= maxcsfrag)); 4252 } 4253 4254 struct csfrag * 4255 findcsfrag(daddr32_t frag, struct csfrag **cfap) 4256 { 4257 struct csfrag *cfp; 4258 4259 if (!csfraginrange(frag)) 4260 return (NULL); 4261 4262 for (cfp = *cfap; cfp; cfp = cfp->next) 4263 if (cfp->ofrag == frag) 4264 return (cfp); 4265 return (NULL); 4266 } 4267 4268 void 4269 checkindirect(ino_t ino, daddr32_t *fragsp, daddr32_t frag, int level) 4270 { 4271 int i; 4272 int ne = sblock.fs_bsize / sizeof (daddr32_t); 4273 daddr32_t fsb[MAXBSIZE / sizeof (daddr32_t)]; 4274 4275 if (frag == 0) 4276 return; 4277 4278 rdfs(fsbtodb(&sblock, frag), (int)sblock.fs_bsize, 4279 (char *)fsb); 4280 4281 checkdirect(ino, fragsp, fsb, sblock.fs_bsize / sizeof (daddr32_t)); 4282 4283 if (level) 4284 for (i = 0; i < ne && *fragsp; ++i) 4285 checkindirect(ino, fragsp, fsb[i], level-1); 4286 } 4287 4288 void 4289 addcsfrag(ino_t ino, daddr32_t frag, struct csfrag **cfap) 4290 { 4291 struct csfrag *cfp, *curr, *prev; 4292 4293 /* 4294 * establish a range for faster checking in csfraginrange() 4295 */ 4296 if (frag > maxcsfrag) 4297 maxcsfrag = frag; 4298 if (frag < mincsfrag) 4299 mincsfrag = frag; 4300 4301 /* 4302 * if this frag belongs to an inode and is not the start of a block 4303 * then see if it is part of a frag range for this inode 4304 */ 4305 if (ino && (frag % sblock.fs_frag)) 4306 for (cfp = *cfap; cfp; cfp = cfp->next) { 4307 if (ino != cfp->ino) 4308 continue; 4309 if (frag != cfp->ofrag + cfp->frags) 4310 continue; 4311 cfp->frags++; 4312 cfp->size += sblock.fs_fsize; 4313 return; 4314 } 4315 /* 4316 * allocate a csfrag entry and insert it in an increasing order into the 4317 * specified list 4318 */ 4319 cfp = (struct csfrag *)calloc(1, sizeof (struct csfrag)); 4320 cfp->ino = ino; 4321 cfp->ofrag = frag; 4322 cfp->frags = 1; 4323 cfp->size = sblock.fs_fsize; 4324 for (prev = NULL, curr = *cfap; curr != NULL; 4325 prev = curr, curr = curr->next) { 4326 if (frag < curr->ofrag) { 4327 cfp->next = curr; 4328 if (prev) 4329 prev->next = cfp; /* middle element */ 4330 else 4331 *cfap = cfp; /* first element */ 4332 break; 4333 } 4334 if (curr->next == NULL) { 4335 curr->next = cfp; /* last element */ 4336 break; 4337 } 4338 } 4339 if (*cfap == NULL) /* will happen only once */ 4340 *cfap = cfp; 4341 } 4342 4343 void 4344 delcsfrag(daddr32_t frag, struct csfrag **cfap) 4345 { 4346 struct csfrag *cfp; 4347 struct csfrag **cfpp; 4348 4349 /* 4350 * free up entry whose beginning frag matches 4351 */ 4352 for (cfpp = cfap; *cfpp; cfpp = &(*cfpp)->next) { 4353 if (frag == (*cfpp)->ofrag) { 4354 cfp = *cfpp; 4355 *cfpp = (*cfpp)->next; 4356 free((char *)cfp); 4357 return; 4358 } 4359 } 4360 } 4361 4362 /* 4363 * See whether any of the direct blocks in the array pointed by "db" and of 4364 * length "ne" are within the range of frags needed to extend the cylinder 4365 * summary. If so, remove those frags from the "as-yet-unclassified" list 4366 * (csfrag) and add them to the "owned-by-inode" list (csfragino). 4367 * For each such frag found, decrement the frag count pointed to by fragsp. 4368 * "ino" is the inode that contains (either directly or indirectly) the frags 4369 * being checked. 4370 */ 4371 void 4372 checkdirect(ino_t ino, daddr32_t *fragsp, daddr32_t *db, int ne) 4373 { 4374 int i; 4375 int j; 4376 int found; 4377 diskaddr_t frag; 4378 4379 /* 4380 * scan for allocation within the new summary info range 4381 */ 4382 for (i = 0; i < ne && *fragsp; ++i) { 4383 if ((frag = *db++) != 0) { 4384 found = 0; 4385 for (j = 0; j < sblock.fs_frag && *fragsp; ++j) { 4386 if (found || (found = csfraginrange(frag))) { 4387 addcsfrag(ino, frag, &csfragino); 4388 delcsfrag(frag, &csfrag); 4389 } 4390 ++frag; 4391 --(*fragsp); 4392 } 4393 } 4394 } 4395 } 4396 4397 void 4398 findcsfragino() 4399 { 4400 int i; 4401 int j; 4402 daddr32_t frags; 4403 struct dinode *dp; 4404 4405 /* 4406 * scan all old inodes looking for allocations in the new 4407 * summary info range. Move the affected frag from the 4408 * generic csfrag list onto the `owned-by-inode' list csfragino. 4409 */ 4410 for (i = UFSROOTINO; i < grow_fs_ncg*sblock.fs_ipg && csfrag; ++i) { 4411 dp = gdinode((ino_t)i); 4412 switch (dp->di_mode & IFMT) { 4413 case IFSHAD : 4414 case IFLNK : 4415 case IFDIR : 4416 case IFREG : break; 4417 default : continue; 4418 } 4419 4420 frags = dbtofsb(&sblock, dp->di_blocks); 4421 4422 checkdirect((ino_t)i, &frags, &dp->di_db[0], NDADDR+NIADDR); 4423 for (j = 0; j < NIADDR && frags; ++j) { 4424 /* Negate the block if its an fallocate'd block */ 4425 if (dp->di_ib[j] < 0 && dp->di_ib[j] != UFS_HOLE) 4426 checkindirect((ino_t)i, &frags, 4427 -(dp->di_ib[j]), j); 4428 else 4429 checkindirect((ino_t)i, &frags, 4430 dp->di_ib[j], j); 4431 } 4432 } 4433 } 4434 4435 void 4436 fixindirect(daddr32_t frag, int level) 4437 { 4438 int i; 4439 int ne = sblock.fs_bsize / sizeof (daddr32_t); 4440 daddr32_t fsb[MAXBSIZE / sizeof (daddr32_t)]; 4441 4442 if (frag == 0) 4443 return; 4444 4445 rdfs(fsbtodb(&sblock, (uint64_t)frag), (int)sblock.fs_bsize, 4446 (char *)fsb); 4447 4448 fixdirect((caddr_t)fsb, frag, fsb, ne); 4449 4450 if (level) 4451 for (i = 0; i < ne; ++i) 4452 fixindirect(fsb[i], level-1); 4453 } 4454 4455 void 4456 fixdirect(caddr_t bp, daddr32_t frag, daddr32_t *db, int ne) 4457 { 4458 int i; 4459 struct csfrag *cfp; 4460 4461 for (i = 0; i < ne; ++i, ++db) { 4462 if (*db == 0) 4463 continue; 4464 if ((cfp = findcsfrag(*db, &csfragino)) == NULL) 4465 continue; 4466 *db = cfp->nfrag; 4467 cfp->fixed = 1; 4468 wtfs(fsbtodb(&sblock, (uint64_t)frag), (int)sblock.fs_bsize, 4469 bp); 4470 } 4471 } 4472 4473 void 4474 fixcsfragino() 4475 { 4476 int i; 4477 struct dinode *dp; 4478 struct csfrag *cfp; 4479 4480 for (cfp = csfragino; cfp; cfp = cfp->next) { 4481 if (cfp->fixed) 4482 continue; 4483 dp = gdinode((ino_t)cfp->ino); 4484 fixdirect((caddr_t)dibuf, difrag, dp->di_db, NDADDR+NIADDR); 4485 for (i = 0; i < NIADDR; ++i) 4486 fixindirect(dp->di_ib[i], i); 4487 } 4488 } 4489 4490 /* 4491 * Read the cylinders summary information specified by settings in the 4492 * passed 'fs' structure into a new allocated array of csum structures. 4493 * The caller is responsible for freeing the returned array. 4494 * Return a pointer to an array of csum structures. 4495 */ 4496 static struct csum * 4497 read_summaryinfo(struct fs *fsp) 4498 { 4499 struct csum *csp; 4500 int i; 4501 4502 if ((csp = malloc((size_t)fsp->fs_cssize)) == NULL) { 4503 (void) fprintf(stderr, gettext("cannot create csum list," 4504 " not enough memory\n")); 4505 exit(32); 4506 } 4507 4508 for (i = 0; i < fsp->fs_cssize; i += fsp->fs_bsize) { 4509 rdfs(fsbtodb(fsp, 4510 (uint64_t)(fsp->fs_csaddr + numfrags(fsp, i))), 4511 (int)(fsp->fs_cssize - i < fsp->fs_bsize ? 4512 fsp->fs_cssize - i : fsp->fs_bsize), 4513 ((caddr_t)csp) + i); 4514 } 4515 4516 return (csp); 4517 } 4518 4519 /* 4520 * Check the allocation of fragments that are to be made part of a csum block. 4521 * A fragment is allocated if it is either in the csfragfree list or, it is 4522 * in the csfragino list and has new frags associated with it. 4523 * Return the number of allocated fragments. 4524 */ 4525 int64_t 4526 checkfragallocated(daddr32_t frag) 4527 { 4528 struct csfrag *cfp; 4529 /* 4530 * Since the lists are sorted we can break the search if the asked 4531 * frag is smaller then the one in the list. 4532 */ 4533 for (cfp = csfragfree; cfp != NULL && frag >= cfp->ofrag; 4534 cfp = cfp->next) { 4535 if (frag == cfp->ofrag) 4536 return (1); 4537 } 4538 for (cfp = csfragino; cfp != NULL && frag >= cfp->ofrag; 4539 cfp = cfp->next) { 4540 if (frag == cfp->ofrag && cfp->nfrag != 0) 4541 return (cfp->frags); 4542 } 4543 4544 return (0); 4545 } 4546 4547 /* 4548 * Figure out how much the filesystem can be grown. The limiting factor is 4549 * the available free space needed to extend the cg summary info block. 4550 * The free space is determined in three steps: 4551 * - Try to extend the cg summary block to the required size. 4552 * - Find free blocks in last cg. 4553 * - Find free space in the last already allocated fragment of the summary info 4554 * block, and use it for additional csum structures. 4555 * Return the maximum size of the new filesystem or 0 if it can't be grown. 4556 * Please note that this function leaves the global list pointers csfrag, 4557 * csfragfree, and csfragino initialized, and the caller is responsible for 4558 * freeing the lists. 4559 */ 4560 diskaddr_t 4561 probe_summaryinfo() 4562 { 4563 /* fragments by which the csum block can be extended. */ 4564 int64_t growth_csum_frags = 0; 4565 /* fragments by which the filesystem can be extended. */ 4566 int64_t growth_fs_frags = 0; 4567 int64_t new_fs_cssize; /* size of csum blk in the new FS */ 4568 int64_t new_fs_ncg; /* number of cg in the new FS */ 4569 int64_t spare_csum; 4570 daddr32_t oldfrag_daddr; 4571 daddr32_t newfrag_daddr; 4572 daddr32_t daddr; 4573 int i; 4574 4575 /* 4576 * read and verify the superblock 4577 */ 4578 rdfs((diskaddr_t)(SBOFF / sectorsize), (int)sbsize, (char *)&sblock); 4579 (void) checksblock(sblock, 0); 4580 4581 /* 4582 * check how much we can extend the cg summary info block 4583 */ 4584 4585 /* 4586 * read current summary information 4587 */ 4588 fscs = read_summaryinfo(&sblock); 4589 4590 /* 4591 * build list of frags needed for cg summary info block extension 4592 */ 4593 oldfrag_daddr = howmany(sblock.fs_cssize, sblock.fs_fsize) + 4594 sblock.fs_csaddr; 4595 new_fs_ncg = howmany(dbtofsb(&sblock, fssize_db), sblock.fs_fpg); 4596 new_fs_cssize = fragroundup(&sblock, new_fs_ncg * sizeof (struct csum)); 4597 newfrag_daddr = howmany(new_fs_cssize, sblock.fs_fsize) + 4598 sblock.fs_csaddr; 4599 /* 4600 * add all of the frags that are required to grow the cyl summary to the 4601 * csfrag list, which is the generic/unknown list, since at this point 4602 * we don't yet know the state of those frags. 4603 */ 4604 for (daddr = oldfrag_daddr; daddr < newfrag_daddr; daddr++) 4605 addcsfrag((ino_t)0, daddr, &csfrag); 4606 4607 /* 4608 * filter free fragments and allocate them. Note that the free frags 4609 * must be allocated first otherwise they could be grabbed by 4610 * alloccsfragino() for data frags. 4611 */ 4612 findcsfragfree(); 4613 alloccsfragfree(); 4614 4615 /* 4616 * filter fragments owned by inodes and allocate them 4617 */ 4618 grow_fs_ncg = sblock.fs_ncg; /* findcsfragino() needs this glob. var. */ 4619 findcsfragino(); 4620 alloccsfragino(); 4621 4622 if (notenoughspace()) { 4623 /* 4624 * check how many consecutive fragments could be allocated 4625 * in both lists. 4626 */ 4627 int64_t tmp_frags; 4628 for (daddr = oldfrag_daddr; daddr < newfrag_daddr; 4629 daddr += tmp_frags) { 4630 if ((tmp_frags = checkfragallocated(daddr)) > 0) 4631 growth_csum_frags += tmp_frags; 4632 else 4633 break; 4634 } 4635 } else { 4636 /* 4637 * We have all we need for the new desired size, 4638 * so clean up and report back. 4639 */ 4640 return (fssize_db); 4641 } 4642 4643 /* 4644 * given the number of fragments by which the csum block can be grown 4645 * compute by how many new fragments the FS can be increased. 4646 * It is the number of csum instances per fragment multiplied by 4647 * `growth_csum_frags' and the number of fragments per cylinder group. 4648 */ 4649 growth_fs_frags = howmany(sblock.fs_fsize, sizeof (struct csum)) * 4650 growth_csum_frags * sblock.fs_fpg; 4651 4652 /* 4653 * compute free fragments in the last cylinder group 4654 */ 4655 rdcg(sblock.fs_ncg - 1); 4656 growth_fs_frags += sblock.fs_fpg - acg.cg_ndblk; 4657 4658 /* 4659 * compute how many csum instances are unused in the old csum block. 4660 * For each unused csum instance the FS can be grown by one cylinder 4661 * group without extending the csum block. 4662 */ 4663 spare_csum = howmany(sblock.fs_cssize, sizeof (struct csum)) - 4664 sblock.fs_ncg; 4665 if (spare_csum > 0) 4666 growth_fs_frags += spare_csum * sblock.fs_fpg; 4667 4668 /* 4669 * recalculate the new filesystem size in sectors, shorten it by 4670 * the requested size `fssize_db' if necessary. 4671 */ 4672 if (growth_fs_frags > 0) { 4673 diskaddr_t sect; 4674 sect = (sblock.fs_size + growth_fs_frags) * sblock.fs_nspf; 4675 return ((sect > fssize_db) ? fssize_db : sect); 4676 } 4677 4678 return (0); 4679 } 4680 4681 void 4682 extendsummaryinfo() 4683 { 4684 int64_t i; 4685 int localtest = test; 4686 int64_t frags; 4687 daddr32_t oldfrag; 4688 daddr32_t newfrag; 4689 4690 /* 4691 * if no-write (-N), don't bother 4692 */ 4693 if (Nflag) 4694 return; 4695 4696 again: 4697 flcg(); 4698 /* 4699 * summary info did not change size -- do nothing unless in test mode 4700 */ 4701 if (grow_fs_cssize == sblock.fs_cssize) 4702 if (!localtest) 4703 return; 4704 4705 /* 4706 * build list of frags needed for additional summary information 4707 */ 4708 oldfrag = howmany(grow_fs_cssize, sblock.fs_fsize) + grow_fs_csaddr; 4709 newfrag = howmany(sblock.fs_cssize, sblock.fs_fsize) + grow_fs_csaddr; 4710 /* 4711 * add all of the frags that are required to grow the cyl summary to the 4712 * csfrag list, which is the generic/unknown list, since at this point 4713 * we don't yet know the state of those frags. 4714 */ 4715 for (i = oldfrag, frags = 0; i < newfrag; ++i, ++frags) 4716 addcsfrag((ino_t)0, (diskaddr_t)i, &csfrag); 4717 /* 4718 * reduce the number of data blocks in the file system (fs_dsize) by 4719 * the number of frags that need to be added to the cyl summary 4720 */ 4721 sblock.fs_dsize -= (newfrag - oldfrag); 4722 4723 /* 4724 * In test mode, we move more data than necessary from 4725 * cylinder group 0. The lookup/allocate/move code can be 4726 * better stressed without having to create HUGE file systems. 4727 */ 4728 if (localtest) 4729 for (i = newfrag; i < grow_sifrag; ++i) { 4730 if (frags >= testfrags) 4731 break; 4732 frags++; 4733 addcsfrag((ino_t)0, (diskaddr_t)i, &csfrag); 4734 } 4735 4736 /* 4737 * move frags to free or inode lists, depending on owner 4738 */ 4739 findcsfragfree(); 4740 findcsfragino(); 4741 4742 /* 4743 * if not all frags can be located, file system must be inconsistent 4744 */ 4745 if (csfrag) { 4746 isbad = 1; /* should already be set, but make sure */ 4747 lockexit(32); 4748 } 4749 4750 /* 4751 * allocate the free frags. Note that the free frags must be allocated 4752 * first otherwise they could be grabbed by alloccsfragino() for data 4753 * frags. 4754 */ 4755 alloccsfragfree(); 4756 /* 4757 * allocate extra space for inode frags 4758 */ 4759 alloccsfragino(); 4760 4761 /* 4762 * not enough space 4763 */ 4764 if (notenoughspace()) { 4765 unalloccsfragfree(); 4766 unalloccsfragino(); 4767 if (localtest && !testforce) { 4768 localtest = 0; 4769 goto again; 4770 } 4771 (void) fprintf(stderr, gettext("Not enough free space\n")); 4772 lockexit(NOTENOUGHSPACE); 4773 } 4774 4775 /* 4776 * copy the data from old frags to new frags 4777 */ 4778 copycsfragino(); 4779 4780 /* 4781 * fix the inodes to point to the new frags 4782 */ 4783 fixcsfragino(); 4784 4785 /* 4786 * We may have moved more frags than we needed. Free them. 4787 */ 4788 rdcg((long)0); 4789 for (i = newfrag; i <= maxcsfrag; ++i) 4790 setbit(cg_blksfree(&acg), i-cgbase(&sblock, 0)); 4791 wtcg(); 4792 4793 flcg(); 4794 } 4795 4796 /* 4797 * Check if all fragments in the `csfragino' list were reallocated. 4798 */ 4799 int 4800 notenoughspace() 4801 { 4802 struct csfrag *cfp; 4803 4804 /* 4805 * If any element in the csfragino array has a "new frag location" 4806 * of 0, the allocfrags() function was unsuccessful in allocating 4807 * space for moving the frag represented by this array element. 4808 */ 4809 for (cfp = csfragino; cfp; cfp = cfp->next) 4810 if (cfp->nfrag == 0) 4811 return (1); 4812 return (0); 4813 } 4814 4815 void 4816 unalloccsfragino() 4817 { 4818 struct csfrag *cfp; 4819 4820 while ((cfp = csfragino) != NULL) { 4821 if (cfp->nfrag) 4822 freefrags(cfp->nfrag, cfp->frags, cfp->cylno); 4823 delcsfrag(cfp->ofrag, &csfragino); 4824 } 4825 } 4826 4827 void 4828 unalloccsfragfree() 4829 { 4830 struct csfrag *cfp; 4831 4832 while ((cfp = csfragfree) != NULL) { 4833 freefrags(cfp->ofrag, cfp->frags, cfp->cylno); 4834 delcsfrag(cfp->ofrag, &csfragfree); 4835 } 4836 } 4837 4838 /* 4839 * For each frag in the "as-yet-unclassified" list (csfrag), see if 4840 * it's free (i.e., its bit is set in the free frag bit map). If so, 4841 * move it from the "as-yet-unclassified" list to the csfragfree list. 4842 */ 4843 void 4844 findcsfragfree() 4845 { 4846 struct csfrag *cfp; 4847 struct csfrag *cfpnext; 4848 4849 /* 4850 * move free frags onto the free-frag list 4851 */ 4852 rdcg((long)0); 4853 for (cfp = csfrag; cfp; cfp = cfpnext) { 4854 cfpnext = cfp->next; 4855 if (isset(cg_blksfree(&acg), cfp->ofrag - cgbase(&sblock, 0))) { 4856 addcsfrag(cfp->ino, cfp->ofrag, &csfragfree); 4857 delcsfrag(cfp->ofrag, &csfrag); 4858 } 4859 } 4860 } 4861 4862 void 4863 copycsfragino() 4864 { 4865 struct csfrag *cfp; 4866 char buf[MAXBSIZE]; 4867 4868 /* 4869 * copy data from old frags to newly allocated frags 4870 */ 4871 for (cfp = csfragino; cfp; cfp = cfp->next) { 4872 rdfs(fsbtodb(&sblock, (uint64_t)cfp->ofrag), (int)cfp->size, 4873 buf); 4874 wtfs(fsbtodb(&sblock, (uint64_t)cfp->nfrag), (int)cfp->size, 4875 buf); 4876 } 4877 } 4878 4879 long curcylno = -1; 4880 int cylnodirty = 0; 4881 4882 void 4883 rdcg(long cylno) 4884 { 4885 if (cylno != curcylno) { 4886 flcg(); 4887 curcylno = cylno; 4888 rdfs(fsbtodb(&sblock, (uint64_t)cgtod(&sblock, curcylno)), 4889 (int)sblock.fs_cgsize, (char *)&acg); 4890 } 4891 } 4892 4893 void 4894 flcg() 4895 { 4896 if (cylnodirty) { 4897 if (debug && Pflag) { 4898 (void) fprintf(stderr, 4899 "Assert: cylnodirty set in probe mode\n"); 4900 return; 4901 } 4902 resetallocinfo(); 4903 wtfs(fsbtodb(&sblock, (uint64_t)cgtod(&sblock, curcylno)), 4904 (int)sblock.fs_cgsize, (char *)&acg); 4905 cylnodirty = 0; 4906 } 4907 curcylno = -1; 4908 } 4909 4910 void 4911 wtcg() 4912 { 4913 if (!Pflag) { 4914 /* probe mode should never write to disk */ 4915 cylnodirty = 1; 4916 } 4917 } 4918 4919 void 4920 allocfrags(long frags, daddr32_t *fragp, long *cylnop) 4921 { 4922 int i; 4923 int j; 4924 long bits; 4925 long bit; 4926 4927 /* 4928 * Allocate a free-frag range in an old cylinder group 4929 */ 4930 for (i = 0, *fragp = 0; i < grow_fs_ncg; ++i) { 4931 if (((fscs+i)->cs_nffree < frags) && ((fscs+i)->cs_nbfree == 0)) 4932 continue; 4933 rdcg((long)i); 4934 bit = bits = 0; 4935 while (findfreerange(&bit, &bits)) { 4936 if (frags <= bits) { 4937 for (j = 0; j < frags; ++j) 4938 clrbit(cg_blksfree(&acg), bit+j); 4939 wtcg(); 4940 *cylnop = i; 4941 *fragp = bit + cgbase(&sblock, i); 4942 return; 4943 } 4944 bit += bits; 4945 } 4946 } 4947 } 4948 4949 /* 4950 * Allocate space for frags that need to be moved in order to free up space for 4951 * expanding the cylinder summary info. 4952 * For each frag that needs to be moved (each frag or range of frags in 4953 * the csfragino list), allocate a new location and store the frag number 4954 * of that new location in the nfrag field of the csfrag struct. 4955 * If a new frag can't be allocated for any element in the csfragino list, 4956 * set the new frag number for that element to 0 and return immediately. 4957 * The notenoughspace() function will detect this condition. 4958 */ 4959 void 4960 alloccsfragino() 4961 { 4962 struct csfrag *cfp; 4963 4964 /* 4965 * allocate space for inode frag ranges 4966 */ 4967 for (cfp = csfragino; cfp; cfp = cfp->next) { 4968 allocfrags(cfp->frags, &cfp->nfrag, &cfp->cylno); 4969 if (cfp->nfrag == 0) 4970 break; 4971 } 4972 } 4973 4974 void 4975 alloccsfragfree() 4976 { 4977 struct csfrag *cfp; 4978 4979 /* 4980 * allocate the free frags needed for extended summary info 4981 */ 4982 rdcg((long)0); 4983 4984 for (cfp = csfragfree; cfp; cfp = cfp->next) 4985 clrbit(cg_blksfree(&acg), cfp->ofrag - cgbase(&sblock, 0)); 4986 4987 wtcg(); 4988 } 4989 4990 void 4991 freefrags(daddr32_t frag, long frags, long cylno) 4992 { 4993 int i; 4994 4995 /* 4996 * free frags 4997 */ 4998 rdcg(cylno); 4999 for (i = 0; i < frags; ++i) { 5000 setbit(cg_blksfree(&acg), (frag+i) - cgbase(&sblock, cylno)); 5001 } 5002 wtcg(); 5003 } 5004 5005 int 5006 findfreerange(long *bitp, long *bitsp) 5007 { 5008 long bit; 5009 5010 /* 5011 * find a range of free bits in a cylinder group bit map 5012 */ 5013 for (bit = *bitp, *bitsp = 0; bit < acg.cg_ndblk; ++bit) 5014 if (isset(cg_blksfree(&acg), bit)) 5015 break; 5016 5017 if (bit >= acg.cg_ndblk) 5018 return (0); 5019 5020 *bitp = bit; 5021 *bitsp = 1; 5022 for (++bit; bit < acg.cg_ndblk; ++bit, ++(*bitsp)) { 5023 if ((bit % sblock.fs_frag) == 0) 5024 break; 5025 if (isclr(cg_blksfree(&acg), bit)) 5026 break; 5027 } 5028 return (1); 5029 } 5030 5031 void 5032 resetallocinfo() 5033 { 5034 long cno; 5035 long bit; 5036 long bits; 5037 5038 /* 5039 * Compute the free blocks/frags info and update the appropriate 5040 * inmemory superblock, summary info, and cylinder group fields 5041 */ 5042 sblock.fs_cstotal.cs_nffree -= acg.cg_cs.cs_nffree; 5043 sblock.fs_cstotal.cs_nbfree -= acg.cg_cs.cs_nbfree; 5044 5045 acg.cg_cs.cs_nffree = 0; 5046 acg.cg_cs.cs_nbfree = 0; 5047 5048 bzero((caddr_t)acg.cg_frsum, sizeof (acg.cg_frsum)); 5049 bzero((caddr_t)cg_blktot(&acg), (int)(acg.cg_iusedoff-acg.cg_btotoff)); 5050 5051 bit = bits = 0; 5052 while (findfreerange(&bit, &bits)) { 5053 if (bits == sblock.fs_frag) { 5054 acg.cg_cs.cs_nbfree++; 5055 cno = cbtocylno(&sblock, bit); 5056 cg_blktot(&acg)[cno]++; 5057 cg_blks(&sblock, &acg, cno)[cbtorpos(&sblock, bit)]++; 5058 } else { 5059 acg.cg_cs.cs_nffree += bits; 5060 acg.cg_frsum[bits]++; 5061 } 5062 bit += bits; 5063 } 5064 5065 *(fscs + acg.cg_cgx) = acg.cg_cs; 5066 5067 sblock.fs_cstotal.cs_nffree += acg.cg_cs.cs_nffree; 5068 sblock.fs_cstotal.cs_nbfree += acg.cg_cs.cs_nbfree; 5069 } 5070 5071 void 5072 extendcg(long cylno) 5073 { 5074 int i; 5075 diskaddr_t dupper; 5076 diskaddr_t cbase; 5077 diskaddr_t dmax; 5078 5079 /* 5080 * extend the cylinder group at the end of the old file system 5081 * if it was partially allocated becase of lack of space 5082 */ 5083 flcg(); 5084 rdcg(cylno); 5085 5086 dupper = acg.cg_ndblk; 5087 if (cylno == sblock.fs_ncg - 1) 5088 acg.cg_ncyl = sblock.fs_ncyl - (sblock.fs_cpg * cylno); 5089 else 5090 acg.cg_ncyl = sblock.fs_cpg; 5091 cbase = cgbase(&sblock, cylno); 5092 dmax = cbase + sblock.fs_fpg; 5093 if (dmax > sblock.fs_size) 5094 dmax = sblock.fs_size; 5095 acg.cg_ndblk = dmax - cbase; 5096 5097 for (i = dupper; i < acg.cg_ndblk; ++i) 5098 setbit(cg_blksfree(&acg), i); 5099 5100 sblock.fs_dsize += (acg.cg_ndblk - dupper); 5101 5102 wtcg(); 5103 flcg(); 5104 } 5105 5106 struct lockfs lockfs; 5107 int lockfd; 5108 int islocked; 5109 int lockfskey; 5110 char lockfscomment[128]; 5111 5112 void 5113 ulockfs() 5114 { 5115 /* 5116 * if the file system was locked, unlock it before exiting 5117 */ 5118 if (islocked == 0) 5119 return; 5120 5121 /* 5122 * first, check if the lock held 5123 */ 5124 lockfs.lf_flags = LOCKFS_MOD; 5125 if (ioctl(lockfd, _FIOLFSS, &lockfs) == -1) { 5126 perror(directory); 5127 lockexit(32); 5128 } 5129 5130 if (LOCKFS_IS_MOD(&lockfs)) { 5131 (void) fprintf(stderr, 5132 gettext("FILE SYSTEM CHANGED DURING GROWFS!\n")); 5133 (void) fprintf(stderr, 5134 gettext(" See lockfs(1), umount(1), and fsck(1)\n")); 5135 lockexit(32); 5136 } 5137 /* 5138 * unlock the file system 5139 */ 5140 lockfs.lf_lock = LOCKFS_ULOCK; 5141 lockfs.lf_flags = 0; 5142 lockfs.lf_key = lockfskey; 5143 clockfs(); 5144 if (ioctl(lockfd, _FIOLFS, &lockfs) == -1) { 5145 perror(directory); 5146 lockexit(32); 5147 } 5148 } 5149 5150 void 5151 wlockfs() 5152 { 5153 5154 /* 5155 * if no-write (-N), don't bother 5156 */ 5157 if (Nflag) 5158 return; 5159 /* 5160 * open the mountpoint, and write lock the file system 5161 */ 5162 if ((lockfd = open64(directory, O_RDONLY)) == -1) { 5163 perror(directory); 5164 lockexit(32); 5165 } 5166 5167 /* 5168 * check if it is already locked 5169 */ 5170 if (ioctl(lockfd, _FIOLFSS, &lockfs) == -1) { 5171 perror(directory); 5172 lockexit(32); 5173 } 5174 5175 if (lockfs.lf_lock != LOCKFS_WLOCK) { 5176 lockfs.lf_lock = LOCKFS_WLOCK; 5177 lockfs.lf_flags = 0; 5178 lockfs.lf_key = 0; 5179 clockfs(); 5180 if (ioctl(lockfd, _FIOLFS, &lockfs) == -1) { 5181 perror(directory); 5182 lockexit(32); 5183 } 5184 } 5185 islocked = 1; 5186 lockfskey = lockfs.lf_key; 5187 } 5188 5189 void 5190 clockfs() 5191 { 5192 time_t t; 5193 char *ct; 5194 5195 (void) time(&t); 5196 ct = ctime(&t); 5197 ct[strlen(ct)-1] = '\0'; 5198 5199 (void) sprintf(lockfscomment, "%s -- mkfs pid %d", ct, getpid()); 5200 lockfs.lf_comlen = strlen(lockfscomment)+1; 5201 lockfs.lf_comment = lockfscomment; 5202 } 5203 5204 /* 5205 * Write the csum records and the superblock 5206 */ 5207 void 5208 wtsb() 5209 { 5210 long i; 5211 5212 /* 5213 * write summary information 5214 */ 5215 for (i = 0; i < sblock.fs_cssize; i += sblock.fs_bsize) 5216 wtfs(fsbtodb(&sblock, (uint64_t)(sblock.fs_csaddr + 5217 numfrags(&sblock, i))), 5218 (int)(sblock.fs_cssize - i < sblock.fs_bsize ? 5219 sblock.fs_cssize - i : sblock.fs_bsize), 5220 ((char *)fscs) + i); 5221 5222 /* 5223 * write superblock 5224 */ 5225 sblock.fs_time = mkfstime; 5226 wtfs((diskaddr_t)(SBOFF / sectorsize), sbsize, (char *)&sblock); 5227 } 5228 5229 /* 5230 * Verify that the optimization selection is reasonable, and advance 5231 * the global "string" appropriately. 5232 */ 5233 static char 5234 checkopt(char *optim) 5235 { 5236 char opt; 5237 int limit = strcspn(optim, ","); 5238 5239 switch (limit) { 5240 case 0: /* missing indicator (have comma or nul) */ 5241 (void) fprintf(stderr, gettext( 5242 "mkfs: missing optimization flag reset to `t' (time)\n")); 5243 opt = 't'; 5244 break; 5245 5246 case 1: /* single-character indicator */ 5247 opt = *optim; 5248 if ((opt != 's') && (opt != 't')) { 5249 (void) fprintf(stderr, gettext( 5250 "mkfs: bad optimization value `%c' reset to `t' (time)\n"), 5251 opt); 5252 opt = 't'; 5253 } 5254 break; 5255 5256 default: /* multi-character indicator */ 5257 (void) fprintf(stderr, gettext( 5258 "mkfs: bad optimization value `%*.*s' reset to `t' (time)\n"), 5259 limit, limit, optim); 5260 opt = 't'; 5261 break; 5262 } 5263 5264 string += limit; 5265 5266 return (opt); 5267 } 5268 5269 /* 5270 * Verify that the mtb selection is reasonable, and advance 5271 * the global "string" appropriately. 5272 */ 5273 static char 5274 checkmtb(char *mtbarg) 5275 { 5276 char mtbc; 5277 int limit = strcspn(mtbarg, ","); 5278 5279 switch (limit) { 5280 case 0: /* missing indicator (have comma or nul) */ 5281 (void) fprintf(stderr, gettext( 5282 "mkfs: missing mtb flag reset to `n' (no mtb support)\n")); 5283 mtbc = 'n'; 5284 break; 5285 5286 case 1: /* single-character indicator */ 5287 mtbc = tolower(*mtbarg); 5288 if ((mtbc != 'y') && (mtbc != 'n')) { 5289 (void) fprintf(stderr, gettext( 5290 "mkfs: bad mtb value `%c' reset to `n' (no mtb support)\n"), 5291 mtbc); 5292 mtbc = 'n'; 5293 } 5294 break; 5295 5296 default: /* multi-character indicator */ 5297 (void) fprintf(stderr, gettext( 5298 "mkfs: bad mtb value `%*.*s' reset to `n' (no mtb support)\n"), 5299 limit, limit, mtbarg); 5300 opt = 'n'; 5301 break; 5302 } 5303 5304 string += limit; 5305 5306 return (mtbc); 5307 } 5308 5309 /* 5310 * Verify that a value is in a range. If it is not, resets it to 5311 * its default value if one is supplied, exits otherwise. 5312 * 5313 * When testing, can compare user_supplied to RC_KEYWORD or RC_POSITIONAL. 5314 */ 5315 static void 5316 range_check(long *varp, char *name, long minimum, long maximum, 5317 long def_val, int user_supplied) 5318 { 5319 dprintf(("DeBuG %s : %ld (%ld %ld %ld)\n", 5320 name, *varp, minimum, maximum, def_val)); 5321 5322 if ((*varp < minimum) || (*varp > maximum)) { 5323 if (user_supplied != RC_DEFAULT) { 5324 (void) fprintf(stderr, gettext( 5325 "mkfs: bad value for %s: %ld must be between %ld and %ld\n"), 5326 name, *varp, minimum, maximum); 5327 } 5328 if (def_val != NO_DEFAULT) { 5329 if (user_supplied) { 5330 (void) fprintf(stderr, 5331 gettext("mkfs: %s reset to default %ld\n"), 5332 name, def_val); 5333 } 5334 *varp = def_val; 5335 dprintf(("DeBuG %s : %ld\n", name, *varp)); 5336 return; 5337 } 5338 lockexit(2); 5339 /*NOTREACHED*/ 5340 } 5341 } 5342 5343 /* 5344 * Verify that a value is in a range. If it is not, resets it to 5345 * its default value if one is supplied, exits otherwise. 5346 * 5347 * When testing, can compare user_supplied to RC_KEYWORD or RC_POSITIONAL. 5348 */ 5349 static void 5350 range_check_64(uint64_t *varp, char *name, uint64_t minimum, uint64_t maximum, 5351 uint64_t def_val, int user_supplied) 5352 { 5353 if ((*varp < minimum) || (*varp > maximum)) { 5354 if (user_supplied != RC_DEFAULT) { 5355 (void) fprintf(stderr, gettext( 5356 "mkfs: bad value for %s: %lld must be between %lld and %lld\n"), 5357 name, *varp, minimum, maximum); 5358 } 5359 if (def_val != NO_DEFAULT) { 5360 if (user_supplied) { 5361 (void) fprintf(stderr, 5362 gettext("mkfs: %s reset to default %lld\n"), 5363 name, def_val); 5364 } 5365 *varp = def_val; 5366 return; 5367 } 5368 lockexit(2); 5369 /*NOTREACHED*/ 5370 } 5371 } 5372 5373 /* 5374 * Blocks SIGINT from delivery. Returns the previous mask in the 5375 * buffer provided, so that mask may be later restored. 5376 */ 5377 static void 5378 block_sigint(sigset_t *old_mask) 5379 { 5380 sigset_t block_mask; 5381 5382 if (sigemptyset(&block_mask) < 0) { 5383 fprintf(stderr, gettext("Could not clear signal mask\n")); 5384 lockexit(3); 5385 } 5386 if (sigaddset(&block_mask, SIGINT) < 0) { 5387 fprintf(stderr, gettext("Could not set signal mask\n")); 5388 lockexit(3); 5389 } 5390 if (sigprocmask(SIG_BLOCK, &block_mask, old_mask) < 0) { 5391 fprintf(stderr, gettext("Could not block SIGINT\n")); 5392 lockexit(3); 5393 } 5394 } 5395 5396 /* 5397 * Restores the signal mask that was in force before a call 5398 * to block_sigint(). This may actually still have SIGINT blocked, 5399 * if we've been recursively invoked. 5400 */ 5401 static void 5402 unblock_sigint(sigset_t *old_mask) 5403 { 5404 if (sigprocmask(SIG_UNBLOCK, old_mask, (sigset_t *)NULL) < 0) { 5405 fprintf(stderr, gettext("Could not restore signal mask\n")); 5406 lockexit(3); 5407 } 5408 } 5409 5410 /* 5411 * Attempt to be somewhat graceful about being interrupted, rather than 5412 * just silently leaving the filesystem in an unusable state. 5413 * 5414 * The kernel has blocked SIGINT upon entry, so we don't have to worry 5415 * about recursion if the user starts pounding on the keyboard. 5416 */ 5417 static void 5418 recover_from_sigint(int signum) 5419 { 5420 if (fso > -1) { 5421 if ((Nflag != 0) || confirm_abort()) { 5422 lockexit(4); 5423 } 5424 } 5425 } 5426 5427 static int 5428 confirm_abort(void) 5429 { 5430 char line[80]; 5431 5432 printf(gettext("\n\nAborting at this point will leave the filesystem " 5433 "in an inconsistent\nstate. If you do choose to stop, " 5434 "you will be given instructions on how to\nrecover " 5435 "the filesystem. Do you wish to cancel the filesystem " 5436 "grow\noperation (y/n)?")); 5437 if (getline(stdin, line, sizeof (line)) == EOF) 5438 line[0] = 'y'; 5439 5440 printf("\n"); 5441 if (line[0] == 'y' || line[0] == 'Y') 5442 return (1); 5443 else { 5444 return (0); 5445 } 5446 } 5447 5448 static int 5449 getline(FILE *fp, char *loc, int maxlen) 5450 { 5451 int n; 5452 char *p, *lastloc; 5453 5454 p = loc; 5455 lastloc = &p[maxlen-1]; 5456 while ((n = getc(fp)) != '\n') { 5457 if (n == EOF) 5458 return (EOF); 5459 if (!isspace(n) && p < lastloc) 5460 *p++ = n; 5461 } 5462 *p = 0; 5463 return (p - loc); 5464 } 5465 5466 /* 5467 * Calculate the maximum value of cylinders-per-group for a file 5468 * system with the characteristics: 5469 * 5470 * bsize - file system block size 5471 * fragsize - frag size 5472 * nbpi - number of bytes of disk space per inode 5473 * nrpos - number of rotational positions 5474 * spc - sectors per cylinder 5475 * 5476 * These five characteristic are not adjustable (by this function). 5477 * The only attribute of the file system which IS adjusted by this 5478 * function in order to maximize cylinders-per-group is the proportion 5479 * of the cylinder group overhead block used for the inode map. The 5480 * inode map cannot occupy more than one-third of the cylinder group 5481 * overhead block, but it's OK for it to occupy less than one-third 5482 * of the overhead block. 5483 * 5484 * The setting of nbpi determines one possible value for the maximum 5485 * size of a cylinder group. It does so because it determines the total 5486 * number of inodes in the file system (file system size is fixed, and 5487 * nbpi is fixed, so the total number of inodes is fixed too). The 5488 * cylinder group has to be small enough so that the number of inodes 5489 * in the cylinder group is less than or equal to the number of bits 5490 * in one-third (or whatever proportion is assumed) of a file system 5491 * block. The details of the calculation are: 5492 * 5493 * The macro MAXIpG_B(bsize, inode_divisor) determines the maximum 5494 * number of inodes that can be in a cylinder group, given the 5495 * proportion of the cylinder group overhead block used for the 5496 * inode bitmaps (an inode_divisor of 3 means that 1/3 of the 5497 * block is used for inode bitmaps; an inode_divisor of 12 means 5498 * that 1/12 of the block is used for inode bitmaps.) 5499 * 5500 * Once the number of inodes per cylinder group is known, the 5501 * maximum value of cylinders-per-group (determined by nbpi) 5502 * is calculated by the formula 5503 * 5504 * maxcpg_given_nbpi = (size of a cylinder group)/(size of a cylinder) 5505 * 5506 * = (inodes-per-cg * nbpi)/(spc * DEV_BSIZE) 5507 * 5508 * (Interestingly, the size of the file system never enters 5509 * into this calculation.) 5510 * 5511 * Another possible value for the maximum cylinder group size is determined 5512 * by frag_size and nrpos. The frags in the cylinder group must be 5513 * representable in the frag bitmaps in the cylinder overhead block and the 5514 * rotational positions for each cylinder must be represented in the 5515 * rotational position tables. The calculation of the maximum cpg 5516 * value, given the frag and nrpos vales, is: 5517 * 5518 * maxcpg_given_fragsize = 5519 * (available space in the overhead block) / (size of per-cylinder data) 5520 * 5521 * The available space in the overhead block = 5522 * bsize - sizeof (struct cg) - space_used_for_inode_bitmaps 5523 * 5524 * The size of the per-cylinder data is: 5525 * sizeof(long) # for the "blocks avail per cylinder" field 5526 * + nrpos * sizeof(short) # for the rotational position table entry 5527 * + frags-per-cylinder/NBBY # number of bytes to represent this 5528 * # cylinder in the frag bitmap 5529 * 5530 * The two calculated maximum values of cylinder-per-group will typically 5531 * turn out to be different, since they are derived from two different 5532 * constraints. Usually, maxcpg_given_nbpi is much bigger than 5533 * maxcpg_given_fragsize. But they can be brought together by 5534 * adjusting the proportion of the overhead block dedicated to 5535 * the inode bitmaps. Decreasing the proportion of the cylinder 5536 * group overhead block used for inode maps will decrease 5537 * maxcpg_given_nbpi and increase maxcpg_given_fragsize. 5538 * 5539 * This function calculates the initial values of maxcpg_given_nbpi 5540 * and maxcpg_given_fragsize assuming that 1/3 of the cg overhead 5541 * block is used for inode bitmaps. Then it decreases the proportion 5542 * of the cg overhead block used for inode bitmaps (by increasing 5543 * the value of inode_divisor) until maxcpg_given_nbpi and 5544 * maxcpg_given_fragsize are the same, or stop changing, or 5545 * maxcpg_given_nbpi is less than maxcpg_given_fragsize. 5546 * 5547 * The loop terminates when any of the following occur: 5548 * * maxcpg_given_fragsize is greater than or equal to 5549 * maxcpg_given_nbpi 5550 * * neither maxcpg_given_fragsize nor maxcpg_given_nbpi 5551 * change in the expected direction 5552 * 5553 * The loop is guaranteed to terminate because it only continues 5554 * while maxcpg_given_fragsize and maxcpg_given_nbpi are approaching 5555 * each other. As soon they cross each other, or neither one changes 5556 * in the direction of the other, or one of them moves in the wrong 5557 * direction, the loop completes. 5558 */ 5559 5560 static long 5561 compute_maxcpg(long bsize, long fragsize, long nbpi, long nrpos, long spc) 5562 { 5563 int maxcpg_given_nbpi; /* in cylinders */ 5564 int maxcpg_given_fragsize; /* in cylinders */ 5565 int spf; /* sectors per frag */ 5566 int inode_divisor; 5567 int old_max_given_frag = 0; 5568 int old_max_given_nbpi = INT_MAX; 5569 5570 spf = fragsize / DEV_BSIZE; 5571 inode_divisor = 3; 5572 5573 while (1) { 5574 maxcpg_given_nbpi = 5575 (((int64_t)(MAXIpG_B(bsize, inode_divisor))) * nbpi) / 5576 (DEV_BSIZE * ((int64_t)spc)); 5577 maxcpg_given_fragsize = 5578 (bsize - (sizeof (struct cg)) - (bsize / inode_divisor)) / 5579 (sizeof (long) + nrpos * sizeof (short) + 5580 (spc / spf) / NBBY); 5581 5582 if (maxcpg_given_fragsize >= maxcpg_given_nbpi) 5583 return (maxcpg_given_nbpi); 5584 5585 /* 5586 * If neither value moves toward the other, return the 5587 * least of the old values (we use the old instead of the 5588 * new because: if the old is the same as the new, it 5589 * doesn't matter which ones we use. If one of the 5590 * values changed, but in the wrong direction, the 5591 * new values are suspect. Better use the old. This 5592 * shouldn't happen, but it's best to check. 5593 */ 5594 5595 if (!(maxcpg_given_nbpi < old_max_given_nbpi) && 5596 !(maxcpg_given_fragsize > old_max_given_frag)) 5597 return (MIN(old_max_given_nbpi, old_max_given_frag)); 5598 5599 /* 5600 * This is probably impossible, but if one of the maxcpg 5601 * values moved in the "right" direction and one moved 5602 * in the "wrong" direction (that is, the two values moved 5603 * in the same direction), the previous conditional won't 5604 * recognize that the values aren't converging (since at 5605 * least one value moved in the "right" direction, the 5606 * last conditional says "keep going"). 5607 * 5608 * Just to make absolutely certain that the loop terminates, 5609 * check for one of the values moving in the "wrong" direction 5610 * and terminate the loop if it happens. 5611 */ 5612 5613 if (maxcpg_given_nbpi > old_max_given_nbpi || 5614 maxcpg_given_fragsize < old_max_given_frag) 5615 return (MIN(old_max_given_nbpi, old_max_given_frag)); 5616 5617 old_max_given_nbpi = maxcpg_given_nbpi; 5618 old_max_given_frag = maxcpg_given_fragsize; 5619 5620 inode_divisor++; 5621 } 5622 } 5623 5624 static int 5625 in_64bit_mode(void) 5626 { 5627 /* cmd must be an absolute path, for security */ 5628 char *cmd = "/usr/bin/isainfo -b"; 5629 char buf[BUFSIZ]; 5630 FILE *ptr; 5631 int retval = 0; 5632 5633 putenv("IFS= \t"); 5634 if ((ptr = popen(cmd, "r")) != NULL) { 5635 if (fgets(buf, BUFSIZ, ptr) != NULL && 5636 strncmp(buf, "64", 2) == 0) 5637 retval = 1; 5638 (void) pclose(ptr); 5639 } 5640 return (retval); 5641 } 5642 5643 /* 5644 * validate_size 5645 * 5646 * Return 1 if the device appears to be at least "size" sectors long. 5647 * Return 0 if it's shorter or we can't read it. 5648 */ 5649 5650 static int 5651 validate_size(int fd, diskaddr_t size) 5652 { 5653 char buf[DEV_BSIZE]; 5654 int rc; 5655 5656 if ((llseek(fd, (offset_t)((size - 1) * DEV_BSIZE), SEEK_SET) == -1) || 5657 (read(fd, buf, DEV_BSIZE)) != DEV_BSIZE) 5658 rc = 0; 5659 else 5660 rc = 1; 5661 return (rc); 5662 } 5663 5664 /* 5665 * Print every field of the calculated superblock, along with 5666 * its value. To make parsing easier on the caller, the value 5667 * is printed first, then the name. Additionally, there's only 5668 * one name/value pair per line. All values are reported in 5669 * hexadecimal (with the traditional 0x prefix), as that's slightly 5670 * easier for humans to read. Not that they're expected to, but 5671 * debugging happens. 5672 */ 5673 static void 5674 dump_sblock(void) 5675 { 5676 int row, column, pending, written; 5677 caddr_t source; 5678 5679 if (Rflag) { 5680 pending = sizeof (sblock); 5681 source = (caddr_t)&sblock; 5682 do { 5683 written = write(fileno(stdout), source, pending); 5684 pending -= written; 5685 source += written; 5686 } while ((pending > 0) && (written > 0)); 5687 5688 if (written < 0) { 5689 perror(gettext("Binary dump of superblock failed")); 5690 lockexit(1); 5691 } 5692 return; 5693 } else { 5694 printf("0x%x sblock.fs_link\n", sblock.fs_link); 5695 printf("0x%x sblock.fs_rolled\n", sblock.fs_rolled); 5696 printf("0x%x sblock.fs_sblkno\n", sblock.fs_sblkno); 5697 printf("0x%x sblock.fs_cblkno\n", sblock.fs_cblkno); 5698 printf("0x%x sblock.fs_iblkno\n", sblock.fs_iblkno); 5699 printf("0x%x sblock.fs_dblkno\n", sblock.fs_dblkno); 5700 printf("0x%x sblock.fs_cgoffset\n", sblock.fs_cgoffset); 5701 printf("0x%x sblock.fs_cgmask\n", sblock.fs_cgmask); 5702 printf("0x%x sblock.fs_time\n", sblock.fs_time); 5703 printf("0x%x sblock.fs_size\n", sblock.fs_size); 5704 printf("0x%x sblock.fs_dsize\n", sblock.fs_dsize); 5705 printf("0x%x sblock.fs_ncg\n", sblock.fs_ncg); 5706 printf("0x%x sblock.fs_bsize\n", sblock.fs_bsize); 5707 printf("0x%x sblock.fs_fsize\n", sblock.fs_fsize); 5708 printf("0x%x sblock.fs_frag\n", sblock.fs_frag); 5709 printf("0x%x sblock.fs_minfree\n", sblock.fs_minfree); 5710 printf("0x%x sblock.fs_rotdelay\n", sblock.fs_rotdelay); 5711 printf("0x%x sblock.fs_rps\n", sblock.fs_rps); 5712 printf("0x%x sblock.fs_bmask\n", sblock.fs_bmask); 5713 printf("0x%x sblock.fs_fmask\n", sblock.fs_fmask); 5714 printf("0x%x sblock.fs_bshift\n", sblock.fs_bshift); 5715 printf("0x%x sblock.fs_fshift\n", sblock.fs_fshift); 5716 printf("0x%x sblock.fs_maxcontig\n", sblock.fs_maxcontig); 5717 printf("0x%x sblock.fs_maxbpg\n", sblock.fs_maxbpg); 5718 printf("0x%x sblock.fs_fragshift\n", sblock.fs_fragshift); 5719 printf("0x%x sblock.fs_fsbtodb\n", sblock.fs_fsbtodb); 5720 printf("0x%x sblock.fs_sbsize\n", sblock.fs_sbsize); 5721 printf("0x%x sblock.fs_csmask\n", sblock.fs_csmask); 5722 printf("0x%x sblock.fs_csshift\n", sblock.fs_csshift); 5723 printf("0x%x sblock.fs_nindir\n", sblock.fs_nindir); 5724 printf("0x%x sblock.fs_inopb\n", sblock.fs_inopb); 5725 printf("0x%x sblock.fs_nspf\n", sblock.fs_nspf); 5726 printf("0x%x sblock.fs_optim\n", sblock.fs_optim); 5727 #ifdef _LITTLE_ENDIAN 5728 printf("0x%x sblock.fs_state\n", sblock.fs_state); 5729 #else 5730 printf("0x%x sblock.fs_npsect\n", sblock.fs_npsect); 5731 #endif 5732 printf("0x%x sblock.fs_si\n", sblock.fs_si); 5733 printf("0x%x sblock.fs_trackskew\n", sblock.fs_trackskew); 5734 printf("0x%x sblock.fs_id[0]\n", sblock.fs_id[0]); 5735 printf("0x%x sblock.fs_id[1]\n", sblock.fs_id[1]); 5736 printf("0x%x sblock.fs_csaddr\n", sblock.fs_csaddr); 5737 printf("0x%x sblock.fs_cssize\n", sblock.fs_cssize); 5738 printf("0x%x sblock.fs_cgsize\n", sblock.fs_cgsize); 5739 printf("0x%x sblock.fs_ntrak\n", sblock.fs_ntrak); 5740 printf("0x%x sblock.fs_nsect\n", sblock.fs_nsect); 5741 printf("0x%x sblock.fs_spc\n", sblock.fs_spc); 5742 printf("0x%x sblock.fs_ncyl\n", sblock.fs_ncyl); 5743 printf("0x%x sblock.fs_cpg\n", sblock.fs_cpg); 5744 printf("0x%x sblock.fs_ipg\n", sblock.fs_ipg); 5745 printf("0x%x sblock.fs_fpg\n", sblock.fs_fpg); 5746 printf("0x%x sblock.fs_cstotal\n", sblock.fs_cstotal); 5747 printf("0x%x sblock.fs_fmod\n", sblock.fs_fmod); 5748 printf("0x%x sblock.fs_clean\n", sblock.fs_clean); 5749 printf("0x%x sblock.fs_ronly\n", sblock.fs_ronly); 5750 printf("0x%x sblock.fs_flags\n", sblock.fs_flags); 5751 printf("0x%x sblock.fs_fsmnt\n", sblock.fs_fsmnt); 5752 printf("0x%x sblock.fs_cgrotor\n", sblock.fs_cgrotor); 5753 printf("0x%x sblock.fs_u.fs_csp\n", sblock.fs_u.fs_csp); 5754 printf("0x%x sblock.fs_cpc\n", sblock.fs_cpc); 5755 5756 /* 5757 * No macros are defined for the dimensions of the 5758 * opostbl array. 5759 */ 5760 for (row = 0; row < 16; row++) { 5761 for (column = 0; column < 8; column++) { 5762 printf("0x%x sblock.fs_opostbl[%d][%d]\n", 5763 sblock.fs_opostbl[row][column], 5764 row, column); 5765 } 5766 } 5767 5768 /* 5769 * Ditto the size of sparecon. 5770 */ 5771 for (row = 0; row < 51; row++) { 5772 printf("0x%x sblock.fs_sparecon[%d]\n", 5773 sblock.fs_sparecon[row], row); 5774 } 5775 5776 printf("0x%x sblock.fs_version\n", sblock.fs_version); 5777 printf("0x%x sblock.fs_logbno\n", sblock.fs_logbno); 5778 printf("0x%x sblock.fs_reclaim\n", sblock.fs_reclaim); 5779 printf("0x%x sblock.fs_sparecon2\n", sblock.fs_sparecon2); 5780 #ifdef _LITTLE_ENDIAN 5781 printf("0x%x sblock.fs_npsect\n", sblock.fs_npsect); 5782 #else 5783 printf("0x%x sblock.fs_state\n", sblock.fs_state); 5784 #endif 5785 printf("0x%llx sblock.fs_qbmask\n", sblock.fs_qbmask); 5786 printf("0x%llx sblock.fs_qfmask\n", sblock.fs_qfmask); 5787 printf("0x%x sblock.fs_postblformat\n", sblock.fs_postblformat); 5788 printf("0x%x sblock.fs_nrpos\n", sblock.fs_nrpos); 5789 printf("0x%x sblock.fs_postbloff\n", sblock.fs_postbloff); 5790 printf("0x%x sblock.fs_rotbloff\n", sblock.fs_rotbloff); 5791 printf("0x%x sblock.fs_magic\n", sblock.fs_magic); 5792 5793 /* 5794 * fs_space isn't of much use in this context, so we'll 5795 * just ignore it for now. 5796 */ 5797 } 5798 } 5799