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