1 /* 2 * Copyright (c) 1980, 1989, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * @(#)mkfs.c 8.11 (Berkeley) 5/3/95 34 * $FreeBSD: src/sbin/newfs/mkfs.c,v 1.29.2.6 2001/09/21 19:15:21 dillon Exp $ 35 * $DragonFly: src/sbin/newfs/mkfs.c,v 1.14 2007/05/20 19:29:21 dillon Exp $ 36 */ 37 38 #include "defs.h" 39 40 #ifndef STANDALONE 41 #include <stdlib.h> 42 #else 43 44 extern int atoi(char *); 45 extern char * getenv(char *); 46 47 #ifdef FSIRAND 48 extern long random(void); 49 extern void srandomdev(void); 50 #endif 51 52 #endif /* STANDALONE */ 53 54 /* 55 * make file system for cylinder-group style file systems 56 */ 57 58 /* 59 * We limit the size of the inode map to be no more than a 60 * third of the cylinder group space, since we must leave at 61 * least an equal amount of space for the block map. 62 * 63 * N.B.: MAXIPG must be a multiple of INOPB(fs). 64 */ 65 #define MAXIPG(fs) roundup((fs)->fs_bsize * NBBY / 3, INOPB(fs)) 66 67 #define UMASK 0755 68 #define MAXINOPB (MAXBSIZE / sizeof(struct ufs1_dinode)) 69 #define POWEROF2(num) (((num) & ((num) - 1)) == 0) 70 71 /* 72 * variables set up by front end. 73 */ 74 extern int mfs; /* run as the memory based filesystem */ 75 extern char *mfs_mtpt; /* mount point for mfs */ 76 extern struct stat mfs_mtstat; /* stat prior to mount */ 77 extern int Nflag; /* run mkfs without writing file system */ 78 extern int Oflag; /* format as an 4.3BSD file system */ 79 extern int Uflag; /* enable soft updates for file system */ 80 extern u_long fssize; /* file system size */ 81 extern int ntracks; /* # tracks/cylinder */ 82 extern int nsectors; /* # sectors/track */ 83 extern int nphyssectors; /* # sectors/track including spares */ 84 extern int secpercyl; /* sectors per cylinder */ 85 extern int sectorsize; /* bytes/sector */ 86 extern int realsectorsize; /* bytes/sector in hardware*/ 87 extern int rpm; /* revolutions/minute of drive */ 88 extern int interleave; /* hardware sector interleave */ 89 extern int trackskew; /* sector 0 skew, per track */ 90 extern int fsize; /* fragment size */ 91 extern int bsize; /* block size */ 92 extern int cpg; /* cylinders/cylinder group */ 93 extern int cpgflg; /* cylinders/cylinder group flag was given */ 94 extern int minfree; /* free space threshold */ 95 extern int opt; /* optimization preference (space or time) */ 96 extern int density; /* number of bytes per inode */ 97 extern int maxcontig; /* max contiguous blocks to allocate */ 98 extern int rotdelay; /* rotational delay between blocks */ 99 extern int maxbpg; /* maximum blocks per file in a cyl group */ 100 extern int nrpos; /* # of distinguished rotational positions */ 101 extern int bbsize; /* boot block size */ 102 extern int sbsize; /* superblock size */ 103 extern int avgfilesize; /* expected average file size */ 104 extern int avgfilesperdir; /* expected number of files per directory */ 105 extern u_long memleft; /* virtual memory available */ 106 extern caddr_t membase; /* start address of memory based filesystem */ 107 extern char * filename; 108 extern struct disktab geom; 109 110 extern void fatal(const char *fmt, ...); 111 112 union { 113 struct fs fs; 114 char pad[SBSIZE]; 115 } fsun; 116 #define sblock fsun.fs 117 struct csum *fscs; 118 119 union { 120 struct cg cg; 121 char pad[MAXBSIZE]; 122 } cgun; 123 #define acg cgun.cg 124 125 struct ufs1_dinode zino[MAXBSIZE / sizeof(struct ufs1_dinode)]; 126 127 int fsi, fso; 128 static fsnode_t copyroot; 129 static fsnode_t copyhlinks; 130 #ifdef FSIRAND 131 int randinit; 132 #endif 133 daddr_t alloc(int, int); 134 long calcipg(long, long, off_t *); 135 static int charsperline(void); 136 void clrblock(struct fs *, unsigned char *, int); 137 void fsinit(time_t); 138 void initcg(int, time_t); 139 int isblock(struct fs *, unsigned char *, int); 140 void iput(struct ufs1_dinode *, ino_t); 141 int makedir(struct direct *, int); 142 void parentready(int); 143 void rdfs(daddr_t, int, char *); 144 void setblock(struct fs *, unsigned char *, int); 145 void started(int); 146 void wtfs(daddr_t, int, char *); 147 void wtfsflush(void); 148 149 #ifndef STANDALONE 150 void get_memleft(void); 151 void raise_data_limit(void); 152 #else 153 void free(char *); 154 char * calloc(u_long, u_long); 155 caddr_t malloc(u_long); 156 caddr_t realloc(char *, u_long); 157 #endif 158 159 int mfs_ppid = 0; 160 int parentready_signalled; 161 162 void 163 mkfs(char *fsys, int fi, int fo, const char *mfscopy) 164 { 165 long i, mincpc, mincpg, inospercg; 166 long cylno, rpos, blk, j, emitwarn = 0; 167 long used, mincpgcnt, bpcg; 168 off_t usedb; 169 long mapcramped, inodecramped; 170 long postblsize, rotblsize, totalsbsize; 171 int status, fd; 172 time_t utime; 173 quad_t sizepb; 174 int width; 175 char tmpbuf[100]; /* XXX this will break in about 2,500 years */ 176 177 #ifndef STANDALONE 178 time(&utime); 179 #endif 180 #ifdef FSIRAND 181 if (!randinit) { 182 randinit = 1; 183 srandomdev(); 184 } 185 #endif 186 if (mfs) { 187 int omask; 188 pid_t child; 189 190 mfs_ppid = getpid(); 191 signal(SIGUSR1, parentready); 192 if ((child = fork()) != 0) { 193 /* 194 * Parent 195 */ 196 if (child == -1) 197 err(10, "mfs"); 198 if (mfscopy) 199 copyroot = FSCopy(©hlinks, mfscopy); 200 signal(SIGUSR1, started); 201 kill(child, SIGUSR1); 202 while (waitpid(child, &status, 0) != child) 203 ; 204 exit(WEXITSTATUS(status)); 205 /* NOTREACHED */ 206 } 207 208 /* 209 * Child 210 */ 211 omask = sigblock(sigmask(SIGUSR1)); 212 while (parentready_signalled == 0) 213 sigpause(omask); 214 sigsetmask(omask); 215 #ifdef STANDALONE 216 malloc(0); 217 #else 218 raise_data_limit(); 219 #endif 220 if (filename != NULL) { 221 unsigned char buf[BUFSIZ]; 222 unsigned long l, l1; 223 ssize_t w; 224 225 fd = open(filename, O_RDWR|O_TRUNC|O_CREAT, 0644); 226 if(fd < 0) 227 err(12, "%s", filename); 228 l1 = fssize * sectorsize; 229 if (l1 > BUFSIZ) 230 l1 = BUFSIZ; 231 for (l = 0; l < fssize * (u_long)sectorsize; l += l1) { 232 w = write(fd, buf, l1); 233 if (w < 0 || (u_long)w != l1) 234 err(12, "%s", filename); 235 } 236 membase = mmap( 237 0, 238 fssize * sectorsize, 239 PROT_READ|PROT_WRITE, 240 MAP_SHARED, 241 fd, 242 0); 243 if(membase == MAP_FAILED) 244 err(12, "mmap"); 245 close(fd); 246 } else { 247 #ifndef STANDALONE 248 get_memleft(); 249 #endif 250 if (fssize * (u_long)sectorsize > (memleft - 131072)) 251 fssize = (memleft - 131072) / sectorsize; 252 if ((membase = malloc(fssize * sectorsize)) == NULL) 253 errx(13, "malloc failed"); 254 } 255 } 256 fsi = fi; 257 fso = fo; 258 if (Oflag) { 259 sblock.fs_inodefmt = FS_42INODEFMT; 260 sblock.fs_maxsymlinklen = 0; 261 } else { 262 sblock.fs_inodefmt = FS_44INODEFMT; 263 sblock.fs_maxsymlinklen = MAXSYMLINKLEN; 264 } 265 if (Uflag) 266 sblock.fs_flags |= FS_DOSOFTDEP; 267 /* 268 * Validate the given file system size. 269 * Verify that its last block can actually be accessed. 270 */ 271 if (fssize == 0) 272 printf("preposterous size %lu\n", fssize), exit(13); 273 wtfs(fssize - (realsectorsize / DEV_BSIZE), realsectorsize, 274 (char *)&sblock); 275 /* 276 * collect and verify the sector and track info 277 */ 278 sblock.fs_nsect = nsectors; 279 sblock.fs_ntrak = ntracks; 280 if (sblock.fs_ntrak <= 0) 281 printf("preposterous ntrak %d\n", sblock.fs_ntrak), exit(14); 282 if (sblock.fs_nsect <= 0) 283 printf("preposterous nsect %d\n", sblock.fs_nsect), exit(15); 284 /* 285 * collect and verify the filesystem density info 286 */ 287 sblock.fs_avgfilesize = avgfilesize; 288 sblock.fs_avgfpdir = avgfilesperdir; 289 if (sblock.fs_avgfilesize <= 0) 290 printf("illegal expected average file size %d\n", 291 sblock.fs_avgfilesize), exit(14); 292 if (sblock.fs_avgfpdir <= 0) 293 printf("illegal expected number of files per directory %d\n", 294 sblock.fs_avgfpdir), exit(15); 295 /* 296 * collect and verify the block and fragment sizes 297 */ 298 sblock.fs_bsize = bsize; 299 sblock.fs_fsize = fsize; 300 if (!POWEROF2(sblock.fs_bsize)) { 301 printf("block size must be a power of 2, not %d\n", 302 sblock.fs_bsize); 303 exit(16); 304 } 305 if (!POWEROF2(sblock.fs_fsize)) { 306 printf("fragment size must be a power of 2, not %d\n", 307 sblock.fs_fsize); 308 exit(17); 309 } 310 if (sblock.fs_fsize < sectorsize) { 311 printf("fragment size %d is too small, minimum is %d\n", 312 sblock.fs_fsize, sectorsize); 313 exit(18); 314 } 315 if (sblock.fs_bsize < MINBSIZE) { 316 printf("block size %d is too small, minimum is %d\n", 317 sblock.fs_bsize, MINBSIZE); 318 exit(19); 319 } 320 if (sblock.fs_bsize < sblock.fs_fsize) { 321 printf("block size (%d) cannot be smaller than fragment size (%d)\n", 322 sblock.fs_bsize, sblock.fs_fsize); 323 exit(20); 324 } 325 sblock.fs_bmask = ~(sblock.fs_bsize - 1); 326 sblock.fs_fmask = ~(sblock.fs_fsize - 1); 327 sblock.fs_qbmask = ~sblock.fs_bmask; 328 sblock.fs_qfmask = ~sblock.fs_fmask; 329 for (sblock.fs_bshift = 0, i = sblock.fs_bsize; i > 1; i >>= 1) 330 sblock.fs_bshift++; 331 for (sblock.fs_fshift = 0, i = sblock.fs_fsize; i > 1; i >>= 1) 332 sblock.fs_fshift++; 333 sblock.fs_frag = numfrags(&sblock, sblock.fs_bsize); 334 for (sblock.fs_fragshift = 0, i = sblock.fs_frag; i > 1; i >>= 1) 335 sblock.fs_fragshift++; 336 if (sblock.fs_frag > MAXFRAG) { 337 printf("fragment size %d is too small, minimum with block size %d is %d\n", 338 sblock.fs_fsize, sblock.fs_bsize, 339 sblock.fs_bsize / MAXFRAG); 340 exit(21); 341 } 342 sblock.fs_nrpos = nrpos; 343 sblock.fs_nindir = sblock.fs_bsize / sizeof(daddr_t); 344 sblock.fs_inopb = sblock.fs_bsize / sizeof(struct ufs1_dinode); 345 sblock.fs_nspf = sblock.fs_fsize / sectorsize; 346 for (sblock.fs_fsbtodb = 0, i = NSPF(&sblock); i > 1; i >>= 1) 347 sblock.fs_fsbtodb++; 348 sblock.fs_sblkno = 349 roundup(howmany(bbsize + sbsize, sblock.fs_fsize), sblock.fs_frag); 350 sblock.fs_cblkno = (daddr_t)(sblock.fs_sblkno + 351 roundup(howmany(sbsize, sblock.fs_fsize), sblock.fs_frag)); 352 sblock.fs_iblkno = sblock.fs_cblkno + sblock.fs_frag; 353 sblock.fs_cgoffset = roundup( 354 howmany(sblock.fs_nsect, NSPF(&sblock)), sblock.fs_frag); 355 for (sblock.fs_cgmask = 0xffffffff, i = sblock.fs_ntrak; i > 1; i >>= 1) 356 sblock.fs_cgmask <<= 1; 357 if (!POWEROF2(sblock.fs_ntrak)) 358 sblock.fs_cgmask <<= 1; 359 sblock.fs_maxfilesize = sblock.fs_bsize * NDADDR - 1; 360 for (sizepb = sblock.fs_bsize, i = 0; i < NIADDR; i++) { 361 sizepb *= NINDIR(&sblock); 362 sblock.fs_maxfilesize += sizepb; 363 } 364 /* 365 * Validate specified/determined secpercyl 366 * and calculate minimum cylinders per group. 367 */ 368 sblock.fs_spc = secpercyl; 369 for (sblock.fs_cpc = NSPB(&sblock), i = sblock.fs_spc; 370 sblock.fs_cpc > 1 && (i & 1) == 0; 371 sblock.fs_cpc >>= 1, i >>= 1) 372 /* void */; 373 mincpc = sblock.fs_cpc; 374 bpcg = sblock.fs_spc * sectorsize; 375 inospercg = roundup(bpcg / sizeof(struct ufs1_dinode), INOPB(&sblock)); 376 if (inospercg > MAXIPG(&sblock)) 377 inospercg = MAXIPG(&sblock); 378 used = (sblock.fs_iblkno + inospercg / INOPF(&sblock)) * NSPF(&sblock); 379 mincpgcnt = howmany(sblock.fs_cgoffset * (~sblock.fs_cgmask) + used, 380 sblock.fs_spc); 381 mincpg = roundup(mincpgcnt, mincpc); 382 /* 383 * Ensure that cylinder group with mincpg has enough space 384 * for block maps. 385 */ 386 sblock.fs_cpg = mincpg; 387 sblock.fs_ipg = inospercg; 388 if (maxcontig > 1) 389 sblock.fs_contigsumsize = MIN(maxcontig, FS_MAXCONTIG); 390 mapcramped = 0; 391 while (CGSIZE(&sblock) > (uint32_t)sblock.fs_bsize) { 392 mapcramped = 1; 393 if (sblock.fs_bsize < MAXBSIZE) { 394 sblock.fs_bsize <<= 1; 395 if ((i & 1) == 0) { 396 i >>= 1; 397 } else { 398 sblock.fs_cpc <<= 1; 399 mincpc <<= 1; 400 mincpg = roundup(mincpgcnt, mincpc); 401 sblock.fs_cpg = mincpg; 402 } 403 sblock.fs_frag <<= 1; 404 sblock.fs_fragshift += 1; 405 if (sblock.fs_frag <= MAXFRAG) 406 continue; 407 } 408 if (sblock.fs_fsize == sblock.fs_bsize) { 409 printf("There is no block size that"); 410 printf(" can support this disk\n"); 411 exit(22); 412 } 413 sblock.fs_frag >>= 1; 414 sblock.fs_fragshift -= 1; 415 sblock.fs_fsize <<= 1; 416 sblock.fs_nspf <<= 1; 417 } 418 /* 419 * Ensure that cylinder group with mincpg has enough space for inodes. 420 */ 421 inodecramped = 0; 422 inospercg = calcipg(mincpg, bpcg, &usedb); 423 sblock.fs_ipg = inospercg; 424 while (inospercg > MAXIPG(&sblock)) { 425 inodecramped = 1; 426 if (mincpc == 1 || sblock.fs_frag == 1 || 427 sblock.fs_bsize == MINBSIZE) 428 break; 429 printf("With a block size of %d %s %d\n", sblock.fs_bsize, 430 "minimum bytes per inode is", 431 (int)((mincpg * (off_t)bpcg - usedb) 432 / MAXIPG(&sblock) + 1)); 433 sblock.fs_bsize >>= 1; 434 sblock.fs_frag >>= 1; 435 sblock.fs_fragshift -= 1; 436 mincpc >>= 1; 437 sblock.fs_cpg = roundup(mincpgcnt, mincpc); 438 if (CGSIZE(&sblock) > (uint32_t)sblock.fs_bsize) { 439 sblock.fs_bsize <<= 1; 440 break; 441 } 442 mincpg = sblock.fs_cpg; 443 inospercg = calcipg(mincpg, bpcg, &usedb); 444 sblock.fs_ipg = inospercg; 445 } 446 if (inodecramped) { 447 if (inospercg > MAXIPG(&sblock)) { 448 printf("Minimum bytes per inode is %d\n", 449 (int)((mincpg * (off_t)bpcg - usedb) 450 / MAXIPG(&sblock) + 1)); 451 } else if (!mapcramped) { 452 printf("With %d bytes per inode, ", density); 453 printf("minimum cylinders per group is %ld\n", mincpg); 454 } 455 } 456 if (mapcramped) { 457 printf("With %d sectors per cylinder, ", sblock.fs_spc); 458 printf("minimum cylinders per group is %ld\n", mincpg); 459 } 460 if (inodecramped || mapcramped) { 461 if (sblock.fs_bsize != bsize) 462 printf("%s to be changed from %d to %d\n", 463 "This requires the block size", 464 bsize, sblock.fs_bsize); 465 if (sblock.fs_fsize != fsize) 466 printf("\t%s to be changed from %d to %d\n", 467 "and the fragment size", 468 fsize, sblock.fs_fsize); 469 exit(23); 470 } 471 /* 472 * Calculate the number of cylinders per group 473 */ 474 sblock.fs_cpg = cpg; 475 if (sblock.fs_cpg % mincpc != 0) { 476 printf("%s groups must have a multiple of %ld cylinders\n", 477 cpgflg ? "Cylinder" : "Warning: cylinder", mincpc); 478 sblock.fs_cpg = roundup(sblock.fs_cpg, mincpc); 479 if (!cpgflg) 480 cpg = sblock.fs_cpg; 481 } 482 /* 483 * Must ensure there is enough space for inodes. 484 */ 485 sblock.fs_ipg = calcipg(sblock.fs_cpg, bpcg, &usedb); 486 while (sblock.fs_ipg > MAXIPG(&sblock)) { 487 inodecramped = 1; 488 sblock.fs_cpg -= mincpc; 489 sblock.fs_ipg = calcipg(sblock.fs_cpg, bpcg, &usedb); 490 } 491 /* 492 * Must ensure there is enough space to hold block map. 493 */ 494 while (CGSIZE(&sblock) > (uint32_t)sblock.fs_bsize) { 495 mapcramped = 1; 496 sblock.fs_cpg -= mincpc; 497 sblock.fs_ipg = calcipg(sblock.fs_cpg, bpcg, &usedb); 498 } 499 sblock.fs_fpg = (sblock.fs_cpg * sblock.fs_spc) / NSPF(&sblock); 500 if ((sblock.fs_cpg * sblock.fs_spc) % NSPB(&sblock) != 0) { 501 printf("panic (fs_cpg * fs_spc) %% NSPF != 0"); 502 exit(24); 503 } 504 if (sblock.fs_cpg < mincpg) { 505 printf("cylinder groups must have at least %ld cylinders\n", 506 mincpg); 507 exit(25); 508 } else if (sblock.fs_cpg != cpg) { 509 if (!cpgflg && !mfs) 510 printf("Warning: "); 511 else if (!mapcramped && !inodecramped) 512 exit(26); 513 if (!mfs) { 514 if (mapcramped && inodecramped) 515 printf("Block size and bytes per inode restrict"); 516 else if (mapcramped) 517 printf("Block size restricts"); 518 else 519 printf("Bytes per inode restrict"); 520 printf(" cylinders per group to %d.\n", sblock.fs_cpg); 521 } 522 if (cpgflg) 523 exit(27); 524 } 525 sblock.fs_cgsize = fragroundup(&sblock, CGSIZE(&sblock)); 526 /* 527 * Now have size for file system and nsect and ntrak. 528 * Determine number of cylinders and blocks in the file system. 529 */ 530 sblock.fs_size = fssize = dbtofsb(&sblock, fssize); 531 sblock.fs_ncyl = fssize * NSPF(&sblock) / sblock.fs_spc; 532 if ((long)fssize * NSPF(&sblock) > sblock.fs_ncyl * sblock.fs_spc) { 533 sblock.fs_ncyl++; 534 emitwarn = 1; 535 } 536 if (sblock.fs_ncyl < 1) { 537 printf("file systems must have at least one cylinder\n"); 538 exit(28); 539 } 540 /* 541 * Determine feasability/values of rotational layout tables. 542 * 543 * The size of the rotational layout tables is limited by the 544 * size of the superblock, SBSIZE. The amount of space available 545 * for tables is calculated as (SBSIZE - sizeof (struct fs)). 546 * The size of these tables is inversely proportional to the block 547 * size of the file system. The size increases if sectors per track 548 * are not powers of two, because more cylinders must be described 549 * by the tables before the rotational pattern repeats (fs_cpc). 550 */ 551 sblock.fs_interleave = interleave; 552 sblock.fs_trackskew = trackskew; 553 sblock.fs_npsect = nphyssectors; 554 sblock.fs_postblformat = FS_DYNAMICPOSTBLFMT; 555 sblock.fs_sbsize = fragroundup(&sblock, sizeof(struct fs)); 556 if (sblock.fs_sbsize > SBSIZE) 557 sblock.fs_sbsize = SBSIZE; 558 if (sblock.fs_ntrak == 1) { 559 sblock.fs_cpc = 0; 560 goto next; 561 } 562 postblsize = sblock.fs_nrpos * sblock.fs_cpc * sizeof(int16_t); 563 rotblsize = sblock.fs_cpc * sblock.fs_spc / NSPB(&sblock); 564 totalsbsize = sizeof(struct fs) + rotblsize; 565 if (sblock.fs_nrpos == 8 && sblock.fs_cpc <= 16) { 566 /* use old static table space */ 567 sblock.fs_postbloff = (char *)(&sblock.fs_opostbl[0][0]) - 568 (char *)(&sblock.fs_firstfield); 569 sblock.fs_rotbloff = &sblock.fs_space[0] - 570 (u_char *)(&sblock.fs_firstfield); 571 } else { 572 /* use dynamic table space */ 573 sblock.fs_postbloff = &sblock.fs_space[0] - 574 (u_char *)(&sblock.fs_firstfield); 575 sblock.fs_rotbloff = sblock.fs_postbloff + postblsize; 576 totalsbsize += postblsize; 577 } 578 if (totalsbsize > SBSIZE || 579 sblock.fs_nsect > (1 << NBBY) * NSPB(&sblock)) { 580 printf("%s %s %d %s %d.%s", 581 "Warning: insufficient space in super block for\n", 582 "rotational layout tables with nsect", sblock.fs_nsect, 583 "and ntrak", sblock.fs_ntrak, 584 "\nFile system performance may be impaired.\n"); 585 sblock.fs_cpc = 0; 586 goto next; 587 } 588 sblock.fs_sbsize = fragroundup(&sblock, totalsbsize); 589 if (sblock.fs_sbsize > SBSIZE) 590 sblock.fs_sbsize = SBSIZE; 591 /* 592 * calculate the available blocks for each rotational position 593 */ 594 for (cylno = 0; cylno < sblock.fs_cpc; cylno++) 595 for (rpos = 0; rpos < sblock.fs_nrpos; rpos++) 596 fs_postbl(&sblock, cylno)[rpos] = -1; 597 for (i = (rotblsize - 1) * sblock.fs_frag; 598 i >= 0; i -= sblock.fs_frag) { 599 cylno = cbtocylno(&sblock, i); 600 rpos = cbtorpos(&sblock, i); 601 blk = fragstoblks(&sblock, i); 602 if (fs_postbl(&sblock, cylno)[rpos] == -1) 603 fs_rotbl(&sblock)[blk] = 0; 604 else 605 fs_rotbl(&sblock)[blk] = 606 fs_postbl(&sblock, cylno)[rpos] - blk; 607 fs_postbl(&sblock, cylno)[rpos] = blk; 608 } 609 next: 610 /* 611 * Compute/validate number of cylinder groups. 612 */ 613 sblock.fs_ncg = sblock.fs_ncyl / sblock.fs_cpg; 614 if (sblock.fs_ncyl % sblock.fs_cpg) 615 sblock.fs_ncg++; 616 sblock.fs_dblkno = sblock.fs_iblkno + sblock.fs_ipg / INOPF(&sblock); 617 i = MIN(~sblock.fs_cgmask, sblock.fs_ncg - 1); 618 if (cgdmin(&sblock, i) - cgbase(&sblock, i) >= sblock.fs_fpg) { 619 printf("inode blocks/cyl group (%ld) >= data blocks (%ld)\n", 620 cgdmin(&sblock, i) - cgbase(&sblock, i) / sblock.fs_frag, 621 (long)(sblock.fs_fpg / sblock.fs_frag)); 622 printf("number of cylinders per cylinder group (%d) %s.\n", 623 sblock.fs_cpg, "must be increased"); 624 exit(29); 625 } 626 j = sblock.fs_ncg - 1; 627 if ((i = fssize - j * sblock.fs_fpg) < sblock.fs_fpg && 628 cgdmin(&sblock, j) - cgbase(&sblock, j) > i) { 629 if (j == 0) { 630 printf("Filesystem must have at least %d sectors\n", 631 NSPF(&sblock) * 632 (cgdmin(&sblock, 0) + 3 * sblock.fs_frag)); 633 exit(30); 634 } 635 printf( 636 "Warning: inode blocks/cyl group (%ld) >= data blocks (%ld) in last\n", 637 (cgdmin(&sblock, j) - cgbase(&sblock, j)) / sblock.fs_frag, 638 i / sblock.fs_frag); 639 printf( 640 " cylinder group. This implies %ld sector(s) cannot be allocated.\n", 641 i * NSPF(&sblock)); 642 sblock.fs_ncg--; 643 sblock.fs_ncyl -= sblock.fs_ncyl % sblock.fs_cpg; 644 sblock.fs_size = fssize = sblock.fs_ncyl * sblock.fs_spc / 645 NSPF(&sblock); 646 emitwarn = 0; 647 } 648 if (emitwarn && !mfs) { 649 printf("Warning: %lu sector(s) in last cylinder unallocated\n", 650 sblock.fs_spc - 651 (fssize * NSPF(&sblock) - (sblock.fs_ncyl - 1) 652 * sblock.fs_spc)); 653 } 654 /* 655 * fill in remaining fields of the super block 656 */ 657 sblock.fs_csaddr = cgdmin(&sblock, 0); 658 sblock.fs_cssize = 659 fragroundup(&sblock, sblock.fs_ncg * sizeof(struct csum)); 660 /* 661 * The superblock fields 'fs_csmask' and 'fs_csshift' are no 662 * longer used. However, we still initialise them so that the 663 * filesystem remains compatible with old kernels. 664 */ 665 i = sblock.fs_bsize / sizeof(struct csum); 666 sblock.fs_csmask = ~(i - 1); 667 for (sblock.fs_csshift = 0; i > 1; i >>= 1) 668 sblock.fs_csshift++; 669 fscs = (struct csum *)calloc(1, sblock.fs_cssize); 670 if (fscs == NULL) 671 errx(31, "calloc failed"); 672 sblock.fs_magic = FS_MAGIC; 673 sblock.fs_rotdelay = rotdelay; 674 sblock.fs_minfree = minfree; 675 sblock.fs_maxcontig = maxcontig; 676 sblock.fs_maxbpg = maxbpg; 677 sblock.fs_rps = rpm / 60; 678 sblock.fs_optim = opt; 679 sblock.fs_cgrotor = 0; 680 sblock.fs_cstotal.cs_ndir = 0; 681 sblock.fs_cstotal.cs_nbfree = 0; 682 sblock.fs_cstotal.cs_nifree = 0; 683 sblock.fs_cstotal.cs_nffree = 0; 684 sblock.fs_fmod = 0; 685 sblock.fs_ronly = 0; 686 sblock.fs_clean = 1; 687 #ifdef FSIRAND 688 sblock.fs_id[0] = (long)utime; 689 sblock.fs_id[1] = random(); 690 #endif 691 692 /* 693 * Dump out summary information about file system. 694 */ 695 if (!mfs) { 696 printf("%s:\t%d sectors in %d %s of %d tracks, %d sectors\n", 697 fsys, sblock.fs_size * NSPF(&sblock), sblock.fs_ncyl, 698 "cylinders", sblock.fs_ntrak, sblock.fs_nsect); 699 #define B2MBFACTOR (1 / (1024.0 * 1024.0)) 700 printf("\t%.1fMB in %d cyl groups (%d c/g, %.2fMB/g, %d i/g)%s\n", 701 (float)sblock.fs_size * sblock.fs_fsize * B2MBFACTOR, 702 sblock.fs_ncg, sblock.fs_cpg, 703 (float)sblock.fs_fpg * sblock.fs_fsize * B2MBFACTOR, 704 sblock.fs_ipg, 705 sblock.fs_flags & FS_DOSOFTDEP ? " SOFTUPDATES" : ""); 706 #undef B2MBFACTOR 707 } 708 /* 709 * Now build the cylinders group blocks and 710 * then print out indices of cylinder groups. 711 */ 712 if (!mfs) 713 printf("super-block backups (for fsck -b #) at:\n"); 714 i = 0; 715 width = charsperline(); 716 for (cylno = 0; cylno < sblock.fs_ncg; cylno++) { 717 initcg(cylno, utime); 718 if (mfs) 719 continue; 720 j = snprintf(tmpbuf, sizeof(tmpbuf), " %ld%s", 721 fsbtodb(&sblock, cgsblock(&sblock, cylno)), 722 cylno < (sblock.fs_ncg-1) ? "," : "" ); 723 if (i + j >= width) { 724 printf("\n"); 725 i = 0; 726 } 727 i += j; 728 printf("%s", tmpbuf); 729 fflush(stdout); 730 } 731 if (!mfs) 732 printf("\n"); 733 if (Nflag && !mfs) 734 exit(0); 735 /* 736 * Now construct the initial file system, 737 * then write out the super-block. 738 */ 739 fsinit(utime); 740 sblock.fs_time = utime; 741 wtfs((int)SBOFF / sectorsize, sbsize, (char *)&sblock); 742 for (i = 0; i < sblock.fs_cssize; i += sblock.fs_bsize) 743 wtfs(fsbtodb(&sblock, sblock.fs_csaddr + numfrags(&sblock, i)), 744 sblock.fs_cssize - i < sblock.fs_bsize ? 745 sblock.fs_cssize - i : sblock.fs_bsize, 746 ((char *)fscs) + i); 747 /* 748 * Write out the duplicate super blocks 749 */ 750 for (cylno = 0; cylno < sblock.fs_ncg; cylno++) 751 wtfs(fsbtodb(&sblock, cgsblock(&sblock, cylno)), 752 sbsize, (char *)&sblock); 753 wtfsflush(); 754 755 /* 756 * NOTE: we no longer update information in the disklabel 757 */ 758 759 /* 760 * Notify parent process of success. 761 * Dissociate from session and tty. 762 * 763 * NOTE: We are the child and may receive a SIGINT due 764 * to losing the tty session? XXX 765 */ 766 if (mfs) { 767 /* YYY */ 768 kill(mfs_ppid, SIGUSR1); 769 setsid(); 770 close(0); 771 close(1); 772 close(2); 773 chdir("/"); 774 /* returns to mount_mfs (newfs) and issues the mount */ 775 } 776 } 777 778 /* 779 * Initialize a cylinder group. 780 */ 781 void 782 initcg(int cylno, time_t utime) 783 { 784 daddr_t cbase, d, dlower, dupper, dmax, blkno; 785 long i; 786 unsigned long k; 787 struct csum *cs; 788 #ifdef FSIRAND 789 uint32_t j; 790 #endif 791 792 /* 793 * Determine block bounds for cylinder group. 794 * Allow space for super block summary information in first 795 * cylinder group. 796 */ 797 cbase = cgbase(&sblock, cylno); 798 dmax = cbase + sblock.fs_fpg; 799 if (dmax > sblock.fs_size) 800 dmax = sblock.fs_size; 801 dlower = cgsblock(&sblock, cylno) - cbase; 802 dupper = cgdmin(&sblock, cylno) - cbase; 803 if (cylno == 0) 804 dupper += howmany(sblock.fs_cssize, sblock.fs_fsize); 805 cs = fscs + cylno; 806 memset(&acg, 0, sblock.fs_cgsize); 807 acg.cg_time = utime; 808 acg.cg_magic = CG_MAGIC; 809 acg.cg_cgx = cylno; 810 if (cylno == sblock.fs_ncg - 1) 811 acg.cg_ncyl = sblock.fs_ncyl % sblock.fs_cpg; 812 else 813 acg.cg_ncyl = sblock.fs_cpg; 814 acg.cg_niblk = sblock.fs_ipg; 815 acg.cg_ndblk = dmax - cbase; 816 if (sblock.fs_contigsumsize > 0) 817 acg.cg_nclusterblks = acg.cg_ndblk / sblock.fs_frag; 818 acg.cg_btotoff = &acg.cg_space[0] - (u_char *)(&acg.cg_firstfield); 819 acg.cg_boff = acg.cg_btotoff + sblock.fs_cpg * sizeof(int32_t); 820 acg.cg_iusedoff = acg.cg_boff + 821 sblock.fs_cpg * sblock.fs_nrpos * sizeof(u_int16_t); 822 acg.cg_freeoff = acg.cg_iusedoff + howmany(sblock.fs_ipg, NBBY); 823 if (sblock.fs_contigsumsize <= 0) { 824 acg.cg_nextfreeoff = acg.cg_freeoff + 825 howmany(sblock.fs_cpg * sblock.fs_spc / NSPF(&sblock), NBBY); 826 } else { 827 acg.cg_clustersumoff = acg.cg_freeoff + howmany 828 (sblock.fs_cpg * sblock.fs_spc / NSPF(&sblock), NBBY) - 829 sizeof(u_int32_t); 830 acg.cg_clustersumoff = 831 roundup(acg.cg_clustersumoff, sizeof(u_int32_t)); 832 acg.cg_clusteroff = acg.cg_clustersumoff + 833 (sblock.fs_contigsumsize + 1) * sizeof(u_int32_t); 834 acg.cg_nextfreeoff = acg.cg_clusteroff + howmany 835 (sblock.fs_cpg * sblock.fs_spc / NSPB(&sblock), NBBY); 836 } 837 if (acg.cg_nextfreeoff - (long)(&acg.cg_firstfield) > sblock.fs_cgsize) { 838 printf("Panic: cylinder group too big\n"); 839 exit(37); 840 } 841 acg.cg_cs.cs_nifree += sblock.fs_ipg; 842 if (cylno == 0) { 843 for (k = 0; k < ROOTINO; k++) { 844 setbit(cg_inosused(&acg), k); 845 acg.cg_cs.cs_nifree--; 846 } 847 } 848 for (i = 0; i < sblock.fs_ipg / INOPF(&sblock); i += sblock.fs_frag) { 849 #ifdef FSIRAND 850 for (j = 0; 851 j < sblock.fs_bsize / sizeof(struct ufs1_dinode); 852 j++) { 853 zino[j].di_gen = random(); 854 } 855 #endif 856 wtfs(fsbtodb(&sblock, cgimin(&sblock, cylno) + i), 857 sblock.fs_bsize, (char *)zino); 858 } 859 if (cylno > 0) { 860 /* 861 * In cylno 0, beginning space is reserved 862 * for boot and super blocks. 863 */ 864 for (d = 0; d < dlower; d += sblock.fs_frag) { 865 blkno = d / sblock.fs_frag; 866 setblock(&sblock, cg_blksfree(&acg), blkno); 867 if (sblock.fs_contigsumsize > 0) 868 setbit(cg_clustersfree(&acg), blkno); 869 acg.cg_cs.cs_nbfree++; 870 cg_blktot(&acg)[cbtocylno(&sblock, d)]++; 871 cg_blks(&sblock, &acg, cbtocylno(&sblock, d)) 872 [cbtorpos(&sblock, d)]++; 873 } 874 sblock.fs_dsize += dlower; 875 } 876 sblock.fs_dsize += acg.cg_ndblk - dupper; 877 if ((i = dupper % sblock.fs_frag)) { 878 acg.cg_frsum[sblock.fs_frag - i]++; 879 for (d = dupper + sblock.fs_frag - i; dupper < d; dupper++) { 880 setbit(cg_blksfree(&acg), dupper); 881 acg.cg_cs.cs_nffree++; 882 } 883 } 884 for (d = dupper; d + sblock.fs_frag <= dmax - cbase; ) { 885 blkno = d / sblock.fs_frag; 886 setblock(&sblock, cg_blksfree(&acg), blkno); 887 if (sblock.fs_contigsumsize > 0) 888 setbit(cg_clustersfree(&acg), blkno); 889 acg.cg_cs.cs_nbfree++; 890 cg_blktot(&acg)[cbtocylno(&sblock, d)]++; 891 cg_blks(&sblock, &acg, cbtocylno(&sblock, d)) 892 [cbtorpos(&sblock, d)]++; 893 d += sblock.fs_frag; 894 } 895 if (d < dmax - cbase) { 896 acg.cg_frsum[dmax - cbase - d]++; 897 for (; d < dmax - cbase; d++) { 898 setbit(cg_blksfree(&acg), d); 899 acg.cg_cs.cs_nffree++; 900 } 901 } 902 if (sblock.fs_contigsumsize > 0) { 903 int32_t *sump = cg_clustersum(&acg); 904 u_char *mapp = cg_clustersfree(&acg); 905 int map = *mapp++; 906 int bit = 1; 907 int run = 0; 908 909 for (i = 0; i < acg.cg_nclusterblks; i++) { 910 if ((map & bit) != 0) { 911 run++; 912 } else if (run != 0) { 913 if (run > sblock.fs_contigsumsize) 914 run = sblock.fs_contigsumsize; 915 sump[run]++; 916 run = 0; 917 } 918 if ((i & (NBBY - 1)) != (NBBY - 1)) { 919 bit <<= 1; 920 } else { 921 map = *mapp++; 922 bit = 1; 923 } 924 } 925 if (run != 0) { 926 if (run > sblock.fs_contigsumsize) 927 run = sblock.fs_contigsumsize; 928 sump[run]++; 929 } 930 } 931 sblock.fs_cstotal.cs_ndir += acg.cg_cs.cs_ndir; 932 sblock.fs_cstotal.cs_nffree += acg.cg_cs.cs_nffree; 933 sblock.fs_cstotal.cs_nbfree += acg.cg_cs.cs_nbfree; 934 sblock.fs_cstotal.cs_nifree += acg.cg_cs.cs_nifree; 935 *cs = acg.cg_cs; 936 wtfs(fsbtodb(&sblock, cgtod(&sblock, cylno)), 937 sblock.fs_bsize, (char *)&acg); 938 } 939 940 /* 941 * initialize the file system 942 */ 943 struct ufs1_dinode node; 944 945 #ifdef LOSTDIR 946 #define PREDEFDIR 3 947 #else 948 #define PREDEFDIR 2 949 #endif 950 951 struct direct root_dir[] = { 952 { ROOTINO, sizeof(struct direct), DT_DIR, 1, "." }, 953 { ROOTINO, sizeof(struct direct), DT_DIR, 2, ".." }, 954 #ifdef LOSTDIR 955 { LOSTFOUNDINO, sizeof(struct direct), DT_DIR, 10, "lost+found" }, 956 #endif 957 }; 958 struct odirect { 959 u_long d_ino; 960 u_short d_reclen; 961 u_short d_namlen; 962 u_char d_name[MAXNAMLEN + 1]; 963 } oroot_dir[] = { 964 { ROOTINO, sizeof(struct direct), 1, "." }, 965 { ROOTINO, sizeof(struct direct), 2, ".." }, 966 #ifdef LOSTDIR 967 { LOSTFOUNDINO, sizeof(struct direct), 10, "lost+found" }, 968 #endif 969 }; 970 #ifdef LOSTDIR 971 struct direct lost_found_dir[] = { 972 { LOSTFOUNDINO, sizeof(struct direct), DT_DIR, 1, "." }, 973 { ROOTINO, sizeof(struct direct), DT_DIR, 2, ".." }, 974 { 0, DIRBLKSIZ, 0, 0, 0 }, 975 }; 976 struct odirect olost_found_dir[] = { 977 { LOSTFOUNDINO, sizeof(struct direct), 1, "." }, 978 { ROOTINO, sizeof(struct direct), 2, ".." }, 979 { 0, DIRBLKSIZ, 0, 0 }, 980 }; 981 #endif 982 char buf[MAXBSIZE]; 983 984 void 985 fsinit(time_t utime) 986 { 987 #ifdef LOSTDIR 988 int i; 989 #endif 990 991 /* 992 * initialize the node 993 */ 994 node.di_atime = utime; 995 node.di_mtime = utime; 996 node.di_ctime = utime; 997 #ifdef LOSTDIR 998 /* 999 * create the lost+found directory 1000 */ 1001 if (Oflag) { 1002 makedir((struct direct *)olost_found_dir, 2); 1003 for (i = DIRBLKSIZ; i < sblock.fs_bsize; i += DIRBLKSIZ) 1004 memmove(&buf[i], &olost_found_dir[2], 1005 DIRSIZ(0, &olost_found_dir[2])); 1006 } else { 1007 makedir(lost_found_dir, 2); 1008 for (i = DIRBLKSIZ; i < sblock.fs_bsize; i += DIRBLKSIZ) 1009 memmove(&buf[i], &lost_found_dir[2], 1010 DIRSIZ(0, &lost_found_dir[2])); 1011 } 1012 node.di_mode = IFDIR | UMASK; 1013 node.di_nlink = 2; 1014 node.di_size = sblock.fs_bsize; 1015 node.di_db[0] = alloc(node.di_size, node.di_mode); 1016 node.di_blocks = btodb(fragroundup(&sblock, node.di_size)); 1017 wtfs(fsbtodb(&sblock, node.di_db[0]), node.di_size, buf); 1018 iput(&node, LOSTFOUNDINO); 1019 #endif 1020 /* 1021 * create the root directory 1022 */ 1023 if (mfs) 1024 node.di_mode = IFDIR | 01777; 1025 else 1026 node.di_mode = IFDIR | UMASK; 1027 node.di_nlink = PREDEFDIR; 1028 if (Oflag) 1029 node.di_size = makedir((struct direct *)oroot_dir, PREDEFDIR); 1030 else 1031 node.di_size = makedir(root_dir, PREDEFDIR); 1032 node.di_db[0] = alloc(sblock.fs_fsize, node.di_mode); 1033 node.di_blocks = btodb(fragroundup(&sblock, node.di_size)); 1034 wtfs(fsbtodb(&sblock, node.di_db[0]), sblock.fs_fsize, buf); 1035 iput(&node, ROOTINO); 1036 } 1037 1038 /* 1039 * construct a set of directory entries in "buf". 1040 * return size of directory. 1041 */ 1042 int 1043 makedir(struct direct *protodir, int entries) 1044 { 1045 char *cp; 1046 int i, spcleft; 1047 1048 spcleft = DIRBLKSIZ; 1049 for (cp = buf, i = 0; i < entries - 1; i++) { 1050 protodir[i].d_reclen = DIRSIZ(0, &protodir[i]); 1051 memmove(cp, &protodir[i], protodir[i].d_reclen); 1052 cp += protodir[i].d_reclen; 1053 spcleft -= protodir[i].d_reclen; 1054 } 1055 protodir[i].d_reclen = spcleft; 1056 memmove(cp, &protodir[i], DIRSIZ(0, &protodir[i])); 1057 return (DIRBLKSIZ); 1058 } 1059 1060 /* 1061 * allocate a block or frag 1062 */ 1063 daddr_t 1064 alloc(int size, int mode) 1065 { 1066 int i, frag; 1067 daddr_t d, blkno; 1068 1069 rdfs(fsbtodb(&sblock, cgtod(&sblock, 0)), sblock.fs_cgsize, 1070 (char *)&acg); 1071 if (acg.cg_magic != CG_MAGIC) { 1072 printf("cg 0: bad magic number\n"); 1073 return (0); 1074 } 1075 if (acg.cg_cs.cs_nbfree == 0) { 1076 printf("first cylinder group ran out of space\n"); 1077 return (0); 1078 } 1079 for (d = 0; d < acg.cg_ndblk; d += sblock.fs_frag) 1080 if (isblock(&sblock, cg_blksfree(&acg), d / sblock.fs_frag)) 1081 goto goth; 1082 printf("internal error: can't find block in cyl 0\n"); 1083 return (0); 1084 goth: 1085 blkno = fragstoblks(&sblock, d); 1086 clrblock(&sblock, cg_blksfree(&acg), blkno); 1087 if (sblock.fs_contigsumsize > 0) 1088 clrbit(cg_clustersfree(&acg), blkno); 1089 acg.cg_cs.cs_nbfree--; 1090 sblock.fs_cstotal.cs_nbfree--; 1091 fscs[0].cs_nbfree--; 1092 if (mode & IFDIR) { 1093 acg.cg_cs.cs_ndir++; 1094 sblock.fs_cstotal.cs_ndir++; 1095 fscs[0].cs_ndir++; 1096 } 1097 cg_blktot(&acg)[cbtocylno(&sblock, d)]--; 1098 cg_blks(&sblock, &acg, cbtocylno(&sblock, d))[cbtorpos(&sblock, d)]--; 1099 if (size != sblock.fs_bsize) { 1100 frag = howmany(size, sblock.fs_fsize); 1101 fscs[0].cs_nffree += sblock.fs_frag - frag; 1102 sblock.fs_cstotal.cs_nffree += sblock.fs_frag - frag; 1103 acg.cg_cs.cs_nffree += sblock.fs_frag - frag; 1104 acg.cg_frsum[sblock.fs_frag - frag]++; 1105 for (i = frag; i < sblock.fs_frag; i++) 1106 setbit(cg_blksfree(&acg), d + i); 1107 } 1108 wtfs(fsbtodb(&sblock, cgtod(&sblock, 0)), sblock.fs_cgsize, 1109 (char *)&acg); 1110 return (d); 1111 } 1112 1113 /* 1114 * Calculate number of inodes per group. 1115 */ 1116 long 1117 calcipg(long cylspg, long bpcg, off_t *usedbp) 1118 { 1119 int i; 1120 long ipg, new_ipg, ncg, ncyl; 1121 off_t usedb; 1122 1123 /* 1124 * Prepare to scale by fssize / (number of sectors in cylinder groups). 1125 * Note that fssize is still in sectors, not filesystem blocks. 1126 */ 1127 ncyl = howmany(fssize, (u_int)secpercyl); 1128 ncg = howmany(ncyl, cylspg); 1129 /* 1130 * Iterate a few times to allow for ipg depending on itself. 1131 */ 1132 ipg = 0; 1133 for (i = 0; i < 10; i++) { 1134 usedb = (sblock.fs_iblkno + ipg / INOPF(&sblock)) 1135 * NSPF(&sblock) * (off_t)sectorsize; 1136 new_ipg = (cylspg * (quad_t)bpcg - usedb) / density * fssize 1137 / ncg / secpercyl / cylspg; 1138 new_ipg = roundup(new_ipg, INOPB(&sblock)); 1139 if (new_ipg == ipg) 1140 break; 1141 ipg = new_ipg; 1142 } 1143 *usedbp = usedb; 1144 return (ipg); 1145 } 1146 1147 /* 1148 * Allocate an inode on the disk 1149 */ 1150 void 1151 iput(struct ufs1_dinode *ip, ino_t ino) 1152 { 1153 struct ufs1_dinode inobuf[MAXINOPB]; 1154 daddr_t d; 1155 int c; 1156 1157 #ifdef FSIRAND 1158 ip->di_gen = random(); 1159 #endif 1160 c = ino_to_cg(&sblock, ino); 1161 rdfs(fsbtodb(&sblock, cgtod(&sblock, 0)), sblock.fs_cgsize, 1162 (char *)&acg); 1163 if (acg.cg_magic != CG_MAGIC) { 1164 printf("cg 0: bad magic number\n"); 1165 exit(31); 1166 } 1167 acg.cg_cs.cs_nifree--; 1168 setbit(cg_inosused(&acg), ino); 1169 wtfs(fsbtodb(&sblock, cgtod(&sblock, 0)), sblock.fs_cgsize, 1170 (char *)&acg); 1171 sblock.fs_cstotal.cs_nifree--; 1172 fscs[0].cs_nifree--; 1173 if (ino >= (uint32_t)sblock.fs_ipg * (uint32_t)sblock.fs_ncg) { 1174 printf("fsinit: inode value out of range (%ju).\n", 1175 (uintmax_t)ino); 1176 exit(32); 1177 } 1178 d = fsbtodb(&sblock, ino_to_fsba(&sblock, ino)); 1179 rdfs(d, sblock.fs_bsize, (char *)inobuf); 1180 inobuf[ino_to_fsbo(&sblock, ino)] = *ip; 1181 wtfs(d, sblock.fs_bsize, (char *)inobuf); 1182 } 1183 1184 /* 1185 * Parent notifies child that it can proceed with the newfs and mount 1186 * operation (occurs after parent has copied the underlying filesystem 1187 * if the -C option was specified (for MFS), or immediately after the 1188 * parent forked the child otherwise). 1189 */ 1190 void 1191 parentready(__unused int signo) 1192 { 1193 parentready_signalled = 1; 1194 } 1195 1196 /* 1197 * Notify parent process that the filesystem has created itself successfully. 1198 * 1199 * We have to wait until the mount has actually completed! 1200 */ 1201 void 1202 started(__unused int signo) 1203 { 1204 int retry = 100; /* 10 seconds, 100ms */ 1205 1206 while (mfs_ppid && retry) { 1207 struct stat st; 1208 1209 if ( 1210 stat(mfs_mtpt, &st) < 0 || 1211 st.st_dev != mfs_mtstat.st_dev 1212 ) { 1213 break; 1214 } 1215 usleep(100*1000); 1216 --retry; 1217 } 1218 if (retry == 0) { 1219 fatal("mfs mount failed waiting for mount to go active"); 1220 } else if (copyroot) { 1221 FSPaste(mfs_mtpt, copyroot, copyhlinks); 1222 } 1223 exit(0); 1224 } 1225 1226 #ifdef STANDALONE 1227 /* 1228 * Replace libc function with one suited to our needs. 1229 */ 1230 caddr_t 1231 malloc(u_long size) 1232 { 1233 char *base, *i; 1234 static u_long pgsz; 1235 struct rlimit rlp; 1236 1237 if (pgsz == 0) { 1238 base = sbrk(0); 1239 pgsz = getpagesize() - 1; 1240 i = (char *)((u_long)(base + pgsz) &~ pgsz); 1241 base = sbrk(i - base); 1242 if (getrlimit(RLIMIT_DATA, &rlp) < 0) 1243 warn("getrlimit"); 1244 rlp.rlim_cur = rlp.rlim_max; 1245 if (setrlimit(RLIMIT_DATA, &rlp) < 0) 1246 warn("setrlimit"); 1247 memleft = rlp.rlim_max - (u_long)base; 1248 } 1249 size = (size + pgsz) &~ pgsz; 1250 if (size > memleft) 1251 size = memleft; 1252 memleft -= size; 1253 if (size == 0) 1254 return (0); 1255 return ((caddr_t)sbrk(size)); 1256 } 1257 1258 /* 1259 * Replace libc function with one suited to our needs. 1260 */ 1261 caddr_t 1262 realloc(char *ptr, u_long size) 1263 { 1264 void *p; 1265 1266 if ((p = malloc(size)) == NULL) 1267 return (NULL); 1268 memmove(p, ptr, size); 1269 free(ptr); 1270 return (p); 1271 } 1272 1273 /* 1274 * Replace libc function with one suited to our needs. 1275 */ 1276 char * 1277 calloc(u_long size, u_long numelm) 1278 { 1279 caddr_t base; 1280 1281 size *= numelm; 1282 if ((base = malloc(size)) == NULL) 1283 return (NULL); 1284 memset(base, 0, size); 1285 return (base); 1286 } 1287 1288 /* 1289 * Replace libc function with one suited to our needs. 1290 */ 1291 void 1292 free(char *ptr) 1293 { 1294 1295 /* do not worry about it for now */ 1296 } 1297 1298 #else /* !STANDALONE */ 1299 1300 void 1301 raise_data_limit(void) 1302 { 1303 struct rlimit rlp; 1304 1305 if (getrlimit(RLIMIT_DATA, &rlp) < 0) 1306 warn("getrlimit"); 1307 rlp.rlim_cur = rlp.rlim_max; 1308 if (setrlimit(RLIMIT_DATA, &rlp) < 0) 1309 warn("setrlimit"); 1310 } 1311 1312 #ifdef __ELF__ 1313 extern char *_etext; 1314 #define etext _etext 1315 #else 1316 extern char *etext; 1317 #endif 1318 1319 void 1320 get_memleft(void) 1321 { 1322 static u_long pgsz; 1323 struct rlimit rlp; 1324 u_long freestart; 1325 u_long dstart; 1326 u_long memused; 1327 1328 pgsz = getpagesize() - 1; 1329 dstart = ((u_long)&etext) &~ pgsz; 1330 freestart = ((u_long)((char *)sbrk(0) + pgsz) &~ pgsz); 1331 if (getrlimit(RLIMIT_DATA, &rlp) < 0) 1332 warn("getrlimit"); 1333 memused = freestart - dstart; 1334 memleft = rlp.rlim_cur - memused; 1335 } 1336 #endif /* STANDALONE */ 1337 1338 /* 1339 * read a block from the file system 1340 */ 1341 void 1342 rdfs(daddr_t bno, int size, char *bf) 1343 { 1344 int n; 1345 1346 wtfsflush(); 1347 if (mfs) { 1348 memmove(bf, membase + bno * sectorsize, size); 1349 return; 1350 } 1351 if (lseek(fsi, (off_t)bno * sectorsize, 0) < 0) { 1352 printf("seek error: %ld\n", (long)bno); 1353 err(33, "rdfs"); 1354 } 1355 n = read(fsi, bf, size); 1356 if (n != size) { 1357 printf("read error: %ld\n", (long)bno); 1358 err(34, "rdfs"); 1359 } 1360 } 1361 1362 #define WCSIZE (128 * 1024) 1363 daddr_t wc_sect; /* units of sectorsize */ 1364 int wc_end; /* bytes */ 1365 static char wc[WCSIZE]; /* bytes */ 1366 1367 /* 1368 * Flush dirty write behind buffer. 1369 */ 1370 void 1371 wtfsflush(void) 1372 { 1373 int n; 1374 if (wc_end) { 1375 if (lseek(fso, (off_t)wc_sect * sectorsize, SEEK_SET) < 0) { 1376 printf("seek error: %ld\n", (long)wc_sect); 1377 err(35, "wtfs - writecombine"); 1378 } 1379 n = write(fso, wc, wc_end); 1380 if (n != wc_end) { 1381 printf("write error: %ld\n", (long)wc_sect); 1382 err(36, "wtfs - writecombine"); 1383 } 1384 wc_end = 0; 1385 } 1386 } 1387 1388 /* 1389 * write a block to the file system 1390 */ 1391 void 1392 wtfs(daddr_t bno, int size, char *bf) 1393 { 1394 int n; 1395 int done; 1396 1397 if (mfs) { 1398 memmove(membase + bno * sectorsize, bf, size); 1399 return; 1400 } 1401 if (Nflag) 1402 return; 1403 done = 0; 1404 if (wc_end == 0 && size <= WCSIZE) { 1405 wc_sect = bno; 1406 bcopy(bf, wc, size); 1407 wc_end = size; 1408 if (wc_end < WCSIZE) 1409 return; 1410 done = 1; 1411 } 1412 if ((off_t)wc_sect * sectorsize + wc_end == (off_t)bno * sectorsize && 1413 wc_end + size <= WCSIZE) { 1414 bcopy(bf, wc + wc_end, size); 1415 wc_end += size; 1416 if (wc_end < WCSIZE) 1417 return; 1418 done = 1; 1419 } 1420 wtfsflush(); 1421 if (done) 1422 return; 1423 if (lseek(fso, (off_t)bno * sectorsize, SEEK_SET) < 0) { 1424 printf("seek error: %ld\n", (long)bno); 1425 err(35, "wtfs"); 1426 } 1427 n = write(fso, bf, size); 1428 if (n != size) { 1429 printf("write error: fso %d blk %ld %d/%d\n", 1430 fso, (long)bno, n, size); 1431 err(36, "wtfs"); 1432 } 1433 } 1434 1435 /* 1436 * check if a block is available 1437 */ 1438 int 1439 isblock(struct fs *fs, unsigned char *cp, int h) 1440 { 1441 unsigned char mask; 1442 1443 switch (fs->fs_frag) { 1444 case 8: 1445 return (cp[h] == 0xff); 1446 case 4: 1447 mask = 0x0f << ((h & 0x1) << 2); 1448 return ((cp[h >> 1] & mask) == mask); 1449 case 2: 1450 mask = 0x03 << ((h & 0x3) << 1); 1451 return ((cp[h >> 2] & mask) == mask); 1452 case 1: 1453 mask = 0x01 << (h & 0x7); 1454 return ((cp[h >> 3] & mask) == mask); 1455 default: 1456 #ifdef STANDALONE 1457 printf("isblock bad fs_frag %d\n", fs->fs_frag); 1458 #else 1459 fprintf(stderr, "isblock bad fs_frag %d\n", fs->fs_frag); 1460 #endif 1461 return (0); 1462 } 1463 } 1464 1465 /* 1466 * take a block out of the map 1467 */ 1468 void 1469 clrblock(struct fs *fs, unsigned char *cp, int h) 1470 { 1471 switch ((fs)->fs_frag) { 1472 case 8: 1473 cp[h] = 0; 1474 return; 1475 case 4: 1476 cp[h >> 1] &= ~(0x0f << ((h & 0x1) << 2)); 1477 return; 1478 case 2: 1479 cp[h >> 2] &= ~(0x03 << ((h & 0x3) << 1)); 1480 return; 1481 case 1: 1482 cp[h >> 3] &= ~(0x01 << (h & 0x7)); 1483 return; 1484 default: 1485 #ifdef STANDALONE 1486 printf("clrblock bad fs_frag %d\n", fs->fs_frag); 1487 #else 1488 fprintf(stderr, "clrblock bad fs_frag %d\n", fs->fs_frag); 1489 #endif 1490 return; 1491 } 1492 } 1493 1494 /* 1495 * put a block into the map 1496 */ 1497 void 1498 setblock(struct fs *fs, unsigned char *cp, int h) 1499 { 1500 switch (fs->fs_frag) { 1501 case 8: 1502 cp[h] = 0xff; 1503 return; 1504 case 4: 1505 cp[h >> 1] |= (0x0f << ((h & 0x1) << 2)); 1506 return; 1507 case 2: 1508 cp[h >> 2] |= (0x03 << ((h & 0x3) << 1)); 1509 return; 1510 case 1: 1511 cp[h >> 3] |= (0x01 << (h & 0x7)); 1512 return; 1513 default: 1514 #ifdef STANDALONE 1515 printf("setblock bad fs_frag %d\n", fs->fs_frag); 1516 #else 1517 fprintf(stderr, "setblock bad fs_frag %d\n", fs->fs_frag); 1518 #endif 1519 return; 1520 } 1521 } 1522 1523 /* 1524 * Determine the number of characters in a 1525 * single line. 1526 */ 1527 1528 static int 1529 charsperline(void) 1530 { 1531 int columns; 1532 char *cp; 1533 struct winsize ws; 1534 1535 columns = 0; 1536 if (ioctl(0, TIOCGWINSZ, &ws) != -1) 1537 columns = ws.ws_col; 1538 if (columns == 0 && (cp = getenv("COLUMNS"))) 1539 columns = atoi(cp); 1540 if (columns == 0) 1541 columns = 80; /* last resort */ 1542 return columns; 1543 } 1544