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