xref: /freebsd/sbin/growfs/growfs.c (revision 22cf89c938886d14f5796fc49f9f020c23ea8eaf)
1 /*-
2  * SPDX-License-Identifier: BSD-4-Clause
3  *
4  * Copyright (c) 1980, 1989, 1993 The Regents of the University of California.
5  * Copyright (c) 2000 Christoph Herrmann, Thomas-Henning von Kamptz
6  * Copyright (c) 2012 The FreeBSD Foundation
7  * All rights reserved.
8  *
9  * This code is derived from software contributed to Berkeley by
10  * Christoph Herrmann and Thomas-Henning von Kamptz, Munich and Frankfurt.
11  *
12  * Portions of this software were developed by Edward Tomasz Napierala
13  * under sponsorship from the FreeBSD Foundation.
14  *
15  * Redistribution and use in source and binary forms, with or without
16  * modification, are permitted provided that the following conditions
17  * are met:
18  * 1. Redistributions of source code must retain the above copyright
19  *    notice, this list of conditions and the following disclaimer.
20  * 2. Redistributions in binary form must reproduce the above copyright
21  *    notice, this list of conditions and the following disclaimer in the
22  *    documentation and/or other materials provided with the distribution.
23  * 3. All advertising materials mentioning features or use of this software
24  *    must display the following acknowledgment:
25  *      This product includes software developed by the University of
26  *      California, Berkeley and its contributors, as well as Christoph
27  *      Herrmann and Thomas-Henning von Kamptz.
28  * 4. Neither the name of the University nor the names of its contributors
29  *    may be used to endorse or promote products derived from this software
30  *    without specific prior written permission.
31  *
32  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
33  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
34  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
35  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
36  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
40  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
41  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
42  * SUCH DAMAGE.
43  *
44  * $TSHeader: src/sbin/growfs/growfs.c,v 1.5 2000/12/12 19:31:00 tomsoft Exp $
45  *
46  */
47 
48 #ifndef lint
49 static const char copyright[] =
50 "@(#) Copyright (c) 2000 Christoph Herrmann, Thomas-Henning von Kamptz\n\
51 Copyright (c) 1980, 1989, 1993 The Regents of the University of California.\n\
52 All rights reserved.\n";
53 #endif /* not lint */
54 
55 #include <sys/cdefs.h>
56 #include <sys/param.h>
57 #include <sys/ioctl.h>
58 #include <sys/stat.h>
59 #include <sys/disk.h>
60 #include <sys/ucred.h>
61 #include <sys/mount.h>
62 
63 #include <stdio.h>
64 #include <paths.h>
65 #include <ctype.h>
66 #include <err.h>
67 #include <errno.h>
68 #include <fcntl.h>
69 #include <fstab.h>
70 #include <inttypes.h>
71 #include <limits.h>
72 #include <mntopts.h>
73 #include <paths.h>
74 #include <stdlib.h>
75 #include <stdint.h>
76 #include <string.h>
77 #include <time.h>
78 #include <unistd.h>
79 #include <ufs/ufs/dinode.h>
80 #include <ufs/ffs/fs.h>
81 #include <libutil.h>
82 #include <libufs.h>
83 
84 #include "debug.h"
85 
86 #ifdef FS_DEBUG
87 int	_dbg_lvl_ = (DL_INFO);	/* DL_TRC */
88 #endif /* FS_DEBUG */
89 
90 static union {
91 	struct fs	fs;
92 	char		pad[SBLOCKSIZE];
93 } fsun1, fsun2;
94 #define	sblock	fsun1.fs	/* the new superblock */
95 #define	osblock	fsun2.fs	/* the old superblock */
96 
97 static union {
98 	struct cg	cg;
99 	char		pad[MAXBSIZE];
100 } cgun1, cgun2;
101 #define	acg	cgun1.cg	/* a cylinder cgroup (new) */
102 #define	aocg	cgun2.cg	/* an old cylinder group */
103 
104 static struct csum	*fscs;	/* cylinder summary */
105 
106 static void	growfs(int, int, unsigned int);
107 static void	rdfs(ufs2_daddr_t, size_t, void *, int);
108 static void	wtfs(ufs2_daddr_t, size_t, void *, int, unsigned int);
109 static int	charsperline(void);
110 static void	usage(void);
111 static int	isblock(struct fs *, unsigned char *, int);
112 static void	clrblock(struct fs *, unsigned char *, int);
113 static void	setblock(struct fs *, unsigned char *, int);
114 static void	initcg(int, time_t, int, unsigned int);
115 static void	updjcg(int, time_t, int, int, unsigned int);
116 static void	updcsloc(time_t, int, int, unsigned int);
117 static void	frag_adjust(ufs2_daddr_t, int);
118 static void	updclst(int);
119 static void	cgckhash(struct cg *);
120 
121 /*
122  * Here we actually start growing the file system. We basically read the
123  * cylinder summary from the first cylinder group as we want to update
124  * this on the fly during our various operations. First we handle the
125  * changes in the former last cylinder group. Afterwards we create all new
126  * cylinder groups.  Now we handle the cylinder group containing the
127  * cylinder summary which might result in a relocation of the whole
128  * structure.  In the end we write back the updated cylinder summary, the
129  * new superblock, and slightly patched versions of the super block
130  * copies.
131  */
132 static void
133 growfs(int fsi, int fso, unsigned int Nflag)
134 {
135 	DBG_FUNC("growfs")
136 	time_t modtime;
137 	uint cylno;
138 	int i, j, width;
139 	char tmpbuf[100];
140 
141 	DBG_ENTER;
142 
143 	time(&modtime);
144 
145 	/*
146 	 * Get the cylinder summary into the memory.
147 	 */
148 	fscs = (struct csum *)calloc((size_t)1, (size_t)sblock.fs_cssize);
149 	if (fscs == NULL)
150 		errx(1, "calloc failed");
151 	memcpy(fscs, osblock.fs_csp, osblock.fs_cssize);
152 	free(osblock.fs_csp);
153 	osblock.fs_csp = NULL;
154 	sblock.fs_csp = fscs;
155 
156 #ifdef FS_DEBUG
157 	{
158 		struct csum *dbg_csp;
159 		u_int32_t dbg_csc;
160 		char dbg_line[80];
161 
162 		dbg_csp = fscs;
163 
164 		for (dbg_csc = 0; dbg_csc < osblock.fs_ncg; dbg_csc++) {
165 			snprintf(dbg_line, sizeof(dbg_line),
166 			    "%d. old csum in old location", dbg_csc);
167 			DBG_DUMP_CSUM(&osblock, dbg_line, dbg_csp++);
168 		}
169 	}
170 #endif /* FS_DEBUG */
171 	DBG_PRINT0("fscs read\n");
172 
173 	/*
174 	 * Do all needed changes in the former last cylinder group.
175 	 */
176 	updjcg(osblock.fs_ncg - 1, modtime, fsi, fso, Nflag);
177 
178 	/*
179 	 * Dump out summary information about file system.
180 	 */
181 #ifdef FS_DEBUG
182 #define B2MBFACTOR (1 / (1024.0 * 1024.0))
183 	printf("growfs: %.1fMB (%jd sectors) block size %d, fragment size %d\n",
184 	    (float)sblock.fs_size * sblock.fs_fsize * B2MBFACTOR,
185 	    (intmax_t)fsbtodb(&sblock, sblock.fs_size), sblock.fs_bsize,
186 	    sblock.fs_fsize);
187 	printf("\tusing %d cylinder groups of %.2fMB, %d blks, %d inodes.\n",
188 	    sblock.fs_ncg, (float)sblock.fs_fpg * sblock.fs_fsize * B2MBFACTOR,
189 	    sblock.fs_fpg / sblock.fs_frag, sblock.fs_ipg);
190 	if (sblock.fs_flags & FS_DOSOFTDEP)
191 		printf("\twith soft updates\n");
192 #undef B2MBFACTOR
193 #endif /* FS_DEBUG */
194 
195 	/*
196 	 * Now build the cylinders group blocks and
197 	 * then print out indices of cylinder groups.
198 	 */
199 	printf("super-block backups (for fsck_ffs -b #) at:\n");
200 	i = 0;
201 	width = charsperline();
202 
203 	/*
204 	 * Iterate for only the new cylinder groups.
205 	 */
206 	for (cylno = osblock.fs_ncg; cylno < sblock.fs_ncg; cylno++) {
207 		initcg(cylno, modtime, fso, Nflag);
208 		j = sprintf(tmpbuf, " %jd%s",
209 		    (intmax_t)fsbtodb(&sblock, cgsblock(&sblock, cylno)),
210 		    cylno < (sblock.fs_ncg - 1) ? "," : "" );
211 		if (i + j >= width) {
212 			printf("\n");
213 			i = 0;
214 		}
215 		i += j;
216 		printf("%s", tmpbuf);
217 		fflush(stdout);
218 	}
219 	printf("\n");
220 
221 	/*
222 	 * Do all needed changes in the first cylinder group.
223 	 * allocate blocks in new location
224 	 */
225 	updcsloc(modtime, fsi, fso, Nflag);
226 
227 	/*
228 	 * Clean up the dynamic fields in our superblock.
229 	 *
230 	 * XXX
231 	 * The following fields are currently distributed from the superblock
232 	 * to the copies:
233 	 *     fs_minfree
234 	 *     fs_rotdelay
235 	 *     fs_maxcontig
236 	 *     fs_maxbpg
237 	 *     fs_minfree,
238 	 *     fs_optim
239 	 *     fs_flags
240 	 *
241 	 * We probably should rather change the summary for the cylinder group
242 	 * statistics here to the value of what would be in there, if the file
243 	 * system were created initially with the new size. Therefor we still
244 	 * need to find an easy way of calculating that.
245 	 * Possibly we can try to read the first superblock copy and apply the
246 	 * "diffed" stats between the old and new superblock by still copying
247 	 * certain parameters onto that.
248 	 */
249 	sblock.fs_time = modtime;
250 	sblock.fs_fmod = 0;
251 	sblock.fs_clean = 1;
252 	sblock.fs_ronly = 0;
253 	sblock.fs_cgrotor = 0;
254 	sblock.fs_state = 0;
255 	memset((void *)&sblock.fs_fsmnt, 0, sizeof(sblock.fs_fsmnt));
256 
257 	/*
258 	 * Now write the new superblock, its summary information,
259 	 * and all the alternates back to disk.
260 	 */
261 	if (!Nflag && sbput(fso, &sblock, sblock.fs_ncg) != 0)
262 		errc(2, EIO, "could not write updated superblock");
263 	DBG_PRINT0("fscs written\n");
264 
265 #ifdef FS_DEBUG
266 	{
267 		struct csum	*dbg_csp;
268 		u_int32_t	dbg_csc;
269 		char	dbg_line[80];
270 
271 		dbg_csp = fscs;
272 		for (dbg_csc = 0; dbg_csc < sblock.fs_ncg; dbg_csc++) {
273 			snprintf(dbg_line, sizeof(dbg_line),
274 			    "%d. new csum in new location", dbg_csc);
275 			DBG_DUMP_CSUM(&sblock, dbg_line, dbg_csp++);
276 		}
277 	}
278 #endif /* FS_DEBUG */
279 
280 	DBG_PRINT0("sblock written\n");
281 	DBG_DUMP_FS(&sblock, "new initial sblock");
282 
283 	DBG_PRINT0("sblock copies written\n");
284 	DBG_DUMP_FS(&sblock, "new other sblocks");
285 
286 	DBG_LEAVE;
287 	return;
288 }
289 
290 /*
291  * This creates a new cylinder group structure, for more details please see
292  * the source of newfs(8), as this function is taken over almost unchanged.
293  * As this is never called for the first cylinder group, the special
294  * provisions for that case are removed here.
295  */
296 static void
297 initcg(int cylno, time_t modtime, int fso, unsigned int Nflag)
298 {
299 	DBG_FUNC("initcg")
300 	static caddr_t iobuf;
301 	static long iobufsize;
302 	long blkno, start;
303 	ino_t ino;
304 	ufs2_daddr_t i, cbase, dmax;
305 	struct ufs1_dinode *dp1;
306 	struct ufs2_dinode *dp2;
307 	struct csum *cs;
308 	uint j, d, dupper, dlower;
309 
310 	if (iobuf == NULL) {
311 		iobufsize = 2 * sblock.fs_bsize;
312 		if ((iobuf = malloc(iobufsize)) == NULL)
313 			errx(37, "panic: cannot allocate I/O buffer");
314 		memset(iobuf, '\0', iobufsize);
315 	}
316 	/*
317 	 * Determine block bounds for cylinder group.
318 	 * Allow space for super block summary information in first
319 	 * cylinder group.
320 	 */
321 	cbase = cgbase(&sblock, cylno);
322 	dmax = cbase + sblock.fs_fpg;
323 	if (dmax > sblock.fs_size)
324 		dmax = sblock.fs_size;
325 	dlower = cgsblock(&sblock, cylno) - cbase;
326 	dupper = cgdmin(&sblock, cylno) - cbase;
327 	if (cylno == 0)	/* XXX fscs may be relocated */
328 		dupper += howmany(sblock.fs_cssize, sblock.fs_fsize);
329 	cs = &fscs[cylno];
330 	memset(&acg, 0, sblock.fs_cgsize);
331 	acg.cg_time = modtime;
332 	acg.cg_magic = CG_MAGIC;
333 	acg.cg_cgx = cylno;
334 	acg.cg_niblk = sblock.fs_ipg;
335 	acg.cg_initediblk = MIN(sblock.fs_ipg, 2 * INOPB(&sblock));
336 	acg.cg_ndblk = dmax - cbase;
337 	if (sblock.fs_contigsumsize > 0)
338 		acg.cg_nclusterblks = acg.cg_ndblk / sblock.fs_frag;
339 	start = sizeof(acg);
340 	if (sblock.fs_magic == FS_UFS2_MAGIC) {
341 		acg.cg_iusedoff = start;
342 	} else {
343 		acg.cg_old_ncyl = sblock.fs_old_cpg;
344 		acg.cg_old_time = acg.cg_time;
345 		acg.cg_time = 0;
346 		acg.cg_old_niblk = acg.cg_niblk;
347 		acg.cg_niblk = 0;
348 		acg.cg_initediblk = 0;
349 		acg.cg_old_btotoff = start;
350 		acg.cg_old_boff = acg.cg_old_btotoff +
351 		    sblock.fs_old_cpg * sizeof(int32_t);
352 		acg.cg_iusedoff = acg.cg_old_boff +
353 		    sblock.fs_old_cpg * sizeof(u_int16_t);
354 	}
355 	acg.cg_freeoff = acg.cg_iusedoff + howmany(sblock.fs_ipg, CHAR_BIT);
356 	acg.cg_nextfreeoff = acg.cg_freeoff + howmany(sblock.fs_fpg, CHAR_BIT);
357 	if (sblock.fs_contigsumsize > 0) {
358 		acg.cg_clustersumoff =
359 		    roundup(acg.cg_nextfreeoff, sizeof(u_int32_t));
360 		acg.cg_clustersumoff -= sizeof(u_int32_t);
361 		acg.cg_clusteroff = acg.cg_clustersumoff +
362 		    (sblock.fs_contigsumsize + 1) * sizeof(u_int32_t);
363 		acg.cg_nextfreeoff = acg.cg_clusteroff +
364 		    howmany(fragstoblks(&sblock, sblock.fs_fpg), CHAR_BIT);
365 	}
366 	if (acg.cg_nextfreeoff > (unsigned)sblock.fs_cgsize) {
367 		/*
368 		 * This should never happen as we would have had that panic
369 		 * already on file system creation
370 		 */
371 		errx(37, "panic: cylinder group too big");
372 	}
373 	acg.cg_cs.cs_nifree += sblock.fs_ipg;
374 	if (cylno == 0)
375 		for (ino = 0; ino < UFS_ROOTINO; ino++) {
376 			setbit(cg_inosused(&acg), ino);
377 			acg.cg_cs.cs_nifree--;
378 		}
379 	/*
380 	 * Initialize the initial inode blocks.
381 	 */
382 	dp1 = (struct ufs1_dinode *)(void *)iobuf;
383 	dp2 = (struct ufs2_dinode *)(void *)iobuf;
384 	for (i = 0; i < acg.cg_initediblk; i++) {
385 		if (sblock.fs_magic == FS_UFS1_MAGIC) {
386 			dp1->di_gen = arc4random();
387 			dp1++;
388 		} else {
389 			dp2->di_gen = arc4random();
390 			dp2++;
391 		}
392 	}
393 	wtfs(fsbtodb(&sblock, cgimin(&sblock, cylno)), iobufsize, iobuf,
394 	    fso, Nflag);
395 	/*
396 	 * For the old file system, we have to initialize all the inodes.
397 	 */
398 	if (sblock.fs_magic == FS_UFS1_MAGIC &&
399 	    sblock.fs_ipg > 2 * INOPB(&sblock)) {
400 		for (i = 2 * sblock.fs_frag;
401 		     i < sblock.fs_ipg / INOPF(&sblock);
402 		     i += sblock.fs_frag) {
403 			dp1 = (struct ufs1_dinode *)(void *)iobuf;
404 			for (j = 0; j < INOPB(&sblock); j++) {
405 				dp1->di_gen = arc4random();
406 				dp1++;
407 			}
408 			wtfs(fsbtodb(&sblock, cgimin(&sblock, cylno) + i),
409 			    sblock.fs_bsize, iobuf, fso, Nflag);
410 		}
411 	}
412 	if (cylno > 0) {
413 		/*
414 		 * In cylno 0, beginning space is reserved
415 		 * for boot and super blocks.
416 		 */
417 		for (d = 0; d < dlower; d += sblock.fs_frag) {
418 			blkno = d / sblock.fs_frag;
419 			setblock(&sblock, cg_blksfree(&acg), blkno);
420 			if (sblock.fs_contigsumsize > 0)
421 				setbit(cg_clustersfree(&acg), blkno);
422 			acg.cg_cs.cs_nbfree++;
423 		}
424 		sblock.fs_dsize += dlower;
425 	}
426 	sblock.fs_dsize += acg.cg_ndblk - dupper;
427 	sblock.fs_old_dsize = sblock.fs_dsize;
428 	if ((i = dupper % sblock.fs_frag)) {
429 		acg.cg_frsum[sblock.fs_frag - i]++;
430 		for (d = dupper + sblock.fs_frag - i; dupper < d; dupper++) {
431 			setbit(cg_blksfree(&acg), dupper);
432 			acg.cg_cs.cs_nffree++;
433 		}
434 	}
435 	for (d = dupper; d + sblock.fs_frag <= acg.cg_ndblk;
436 	    d += sblock.fs_frag) {
437 		blkno = d / sblock.fs_frag;
438 		setblock(&sblock, cg_blksfree(&acg), blkno);
439 		if (sblock.fs_contigsumsize > 0)
440 			setbit(cg_clustersfree(&acg), blkno);
441 		acg.cg_cs.cs_nbfree++;
442 	}
443 	if (d < acg.cg_ndblk) {
444 		acg.cg_frsum[acg.cg_ndblk - d]++;
445 		for (; d < acg.cg_ndblk; d++) {
446 			setbit(cg_blksfree(&acg), d);
447 			acg.cg_cs.cs_nffree++;
448 		}
449 	}
450 	if (sblock.fs_contigsumsize > 0) {
451 		int32_t *sump = cg_clustersum(&acg);
452 		u_char *mapp = cg_clustersfree(&acg);
453 		int map = *mapp++;
454 		int bit = 1;
455 		int run = 0;
456 
457 		for (i = 0; i < acg.cg_nclusterblks; i++) {
458 			if ((map & bit) != 0)
459 				run++;
460 			else if (run != 0) {
461 				if (run > sblock.fs_contigsumsize)
462 					run = sblock.fs_contigsumsize;
463 				sump[run]++;
464 				run = 0;
465 			}
466 			if ((i & (CHAR_BIT - 1)) != CHAR_BIT - 1)
467 				bit <<= 1;
468 			else {
469 				map = *mapp++;
470 				bit = 1;
471 			}
472 		}
473 		if (run != 0) {
474 			if (run > sblock.fs_contigsumsize)
475 				run = sblock.fs_contigsumsize;
476 			sump[run]++;
477 		}
478 	}
479 	sblock.fs_cstotal.cs_ndir += acg.cg_cs.cs_ndir;
480 	sblock.fs_cstotal.cs_nffree += acg.cg_cs.cs_nffree;
481 	sblock.fs_cstotal.cs_nbfree += acg.cg_cs.cs_nbfree;
482 	sblock.fs_cstotal.cs_nifree += acg.cg_cs.cs_nifree;
483 	*cs = acg.cg_cs;
484 
485 	cgckhash(&acg);
486 	wtfs(fsbtodb(&sblock, cgtod(&sblock, cylno)), sblock.fs_cgsize, &acg,
487 	    fso, Nflag);
488 	DBG_DUMP_CG(&sblock, "new cg", &acg);
489 
490 	DBG_LEAVE;
491 	return;
492 }
493 
494 /*
495  * Here we add or subtract (sign +1/-1) the available fragments in a given
496  * block to or from the fragment statistics. By subtracting before and adding
497  * after an operation on the free frag map we can easy update the fragment
498  * statistic, which seems to be otherwise a rather complex operation.
499  */
500 static void
501 frag_adjust(ufs2_daddr_t frag, int sign)
502 {
503 	DBG_FUNC("frag_adjust")
504 	int fragsize;
505 	int f;
506 
507 	DBG_ENTER;
508 
509 	fragsize = 0;
510 	/*
511 	 * Here frag only needs to point to any fragment in the block we want
512 	 * to examine.
513 	 */
514 	for (f = rounddown(frag, sblock.fs_frag);
515 	    f < roundup(frag + 1, sblock.fs_frag); f++) {
516 		/*
517 		 * Count contiguous free fragments.
518 		 */
519 		if (isset(cg_blksfree(&acg), f)) {
520 			fragsize++;
521 		} else {
522 			if (fragsize && fragsize < sblock.fs_frag) {
523 				/*
524 				 * We found something in between.
525 				 */
526 				acg.cg_frsum[fragsize] += sign;
527 				DBG_PRINT2("frag_adjust [%d]+=%d\n",
528 				    fragsize, sign);
529 			}
530 			fragsize = 0;
531 		}
532 	}
533 	if (fragsize && fragsize < sblock.fs_frag) {
534 		/*
535 		 * We found something.
536 		 */
537 		acg.cg_frsum[fragsize] += sign;
538 		DBG_PRINT2("frag_adjust [%d]+=%d\n", fragsize, sign);
539 	}
540 	DBG_PRINT2("frag_adjust [[%d]]+=%d\n", fragsize, sign);
541 
542 	DBG_LEAVE;
543 	return;
544 }
545 
546 /*
547  * Here we do all needed work for the former last cylinder group. It has to be
548  * changed in any case, even if the file system ended exactly on the end of
549  * this group, as there is some slightly inconsistent handling of the number
550  * of cylinders in the cylinder group. We start again by reading the cylinder
551  * group from disk. If the last block was not fully available, we first handle
552  * the missing fragments, then we handle all new full blocks in that file
553  * system and finally we handle the new last fragmented block in the file
554  * system.  We again have to handle the fragment statistics rotational layout
555  * tables and cluster summary during all those operations.
556  */
557 static void
558 updjcg(int cylno, time_t modtime, int fsi, int fso, unsigned int Nflag)
559 {
560 	DBG_FUNC("updjcg")
561 	ufs2_daddr_t cbase, dmax;
562 	struct csum *cs;
563 	int i, k;
564 	int j = 0;
565 
566 	DBG_ENTER;
567 
568 	/*
569 	 * Read the former last (joining) cylinder group from disk, and make
570 	 * a copy.
571 	 */
572 	rdfs(fsbtodb(&osblock, cgtod(&osblock, cylno)),
573 	    (size_t)osblock.fs_cgsize, (void *)&aocg, fsi);
574 	DBG_PRINT0("jcg read\n");
575 	DBG_DUMP_CG(&sblock, "old joining cg", &aocg);
576 
577 	memcpy((void *)&cgun1, (void *)&cgun2, sizeof(cgun2));
578 
579 	/*
580 	 * If the cylinder group had already its new final size almost
581 	 * nothing is to be done ... except:
582 	 * For some reason the value of cg_ncyl in the last cylinder group has
583 	 * to be zero instead of fs_cpg. As this is now no longer the last
584 	 * cylinder group we have to change that value now to fs_cpg.
585 	 */
586 
587 	if (cgbase(&osblock, cylno + 1) == osblock.fs_size) {
588 		if (sblock.fs_magic == FS_UFS1_MAGIC)
589 			acg.cg_old_ncyl = sblock.fs_old_cpg;
590 
591 		cgckhash(&acg);
592 		wtfs(fsbtodb(&sblock, cgtod(&sblock, cylno)),
593 		    (size_t)sblock.fs_cgsize, (void *)&acg, fso, Nflag);
594 		DBG_PRINT0("jcg written\n");
595 		DBG_DUMP_CG(&sblock, "new joining cg", &acg);
596 
597 		DBG_LEAVE;
598 		return;
599 	}
600 
601 	/*
602 	 * Set up some variables needed later.
603 	 */
604 	cbase = cgbase(&sblock, cylno);
605 	dmax = cbase + sblock.fs_fpg;
606 	if (dmax > sblock.fs_size)
607 		dmax = sblock.fs_size;
608 
609 	/*
610 	 * Set pointer to the cylinder summary for our cylinder group.
611 	 */
612 	cs = fscs + cylno;
613 
614 	/*
615 	 * Touch the cylinder group, update all fields in the cylinder group as
616 	 * needed, update the free space in the superblock.
617 	 */
618 	acg.cg_time = modtime;
619 	if ((unsigned)cylno == sblock.fs_ncg - 1) {
620 		/*
621 		 * This is still the last cylinder group.
622 		 */
623 		if (sblock.fs_magic == FS_UFS1_MAGIC)
624 			acg.cg_old_ncyl =
625 			    sblock.fs_old_ncyl % sblock.fs_old_cpg;
626 	} else {
627 		acg.cg_old_ncyl = sblock.fs_old_cpg;
628 	}
629 	DBG_PRINT2("jcg dbg: %d %u", cylno, sblock.fs_ncg);
630 #ifdef FS_DEBUG
631 	if (sblock.fs_magic == FS_UFS1_MAGIC)
632 		DBG_PRINT2("%d %u", acg.cg_old_ncyl, sblock.fs_old_cpg);
633 #endif
634 	DBG_PRINT0("\n");
635 	acg.cg_ndblk = dmax - cbase;
636 	sblock.fs_dsize += acg.cg_ndblk - aocg.cg_ndblk;
637 	sblock.fs_old_dsize = sblock.fs_dsize;
638 	if (sblock.fs_contigsumsize > 0)
639 		acg.cg_nclusterblks = acg.cg_ndblk / sblock.fs_frag;
640 
641 	/*
642 	 * Now we have to update the free fragment bitmap for our new free
643 	 * space.  There again we have to handle the fragmentation and also
644 	 * the rotational layout tables and the cluster summary.  This is
645 	 * also done per fragment for the first new block if the old file
646 	 * system end was not on a block boundary, per fragment for the new
647 	 * last block if the new file system end is not on a block boundary,
648 	 * and per block for all space in between.
649 	 *
650 	 * Handle the first new block here if it was partially available
651 	 * before.
652 	 */
653 	if (osblock.fs_size % sblock.fs_frag) {
654 		if (roundup(osblock.fs_size, sblock.fs_frag) <=
655 		    sblock.fs_size) {
656 			/*
657 			 * The new space is enough to fill at least this
658 			 * block
659 			 */
660 			j = 0;
661 			for (i = roundup(osblock.fs_size - cbase,
662 			    sblock.fs_frag) - 1; i >= osblock.fs_size - cbase;
663 			    i--) {
664 				setbit(cg_blksfree(&acg), i);
665 				acg.cg_cs.cs_nffree++;
666 				j++;
667 			}
668 
669 			/*
670 			 * Check if the fragment just created could join an
671 			 * already existing fragment at the former end of the
672 			 * file system.
673 			 */
674 			if (isblock(&sblock, cg_blksfree(&acg),
675 			    ((osblock.fs_size - cgbase(&sblock, cylno)) /
676 			     sblock.fs_frag))) {
677 				/*
678 				 * The block is now completely available.
679 				 */
680 				DBG_PRINT0("block was\n");
681 				acg.cg_frsum[osblock.fs_size % sblock.fs_frag]--;
682 				acg.cg_cs.cs_nbfree++;
683 				acg.cg_cs.cs_nffree -= sblock.fs_frag;
684 				k = rounddown(osblock.fs_size - cbase,
685 				    sblock.fs_frag);
686 				updclst((osblock.fs_size - cbase) /
687 				    sblock.fs_frag);
688 			} else {
689 				/*
690 				 * Lets rejoin a possible partially growed
691 				 * fragment.
692 				 */
693 				k = 0;
694 				while (isset(cg_blksfree(&acg), i) &&
695 				    (i >= rounddown(osblock.fs_size - cbase,
696 				    sblock.fs_frag))) {
697 					i--;
698 					k++;
699 				}
700 				if (k)
701 					acg.cg_frsum[k]--;
702 				acg.cg_frsum[k + j]++;
703 			}
704 		} else {
705 			/*
706 			 * We only grow by some fragments within this last
707 			 * block.
708 			 */
709 			for (i = sblock.fs_size - cbase - 1;
710 			    i >= osblock.fs_size - cbase; i--) {
711 				setbit(cg_blksfree(&acg), i);
712 				acg.cg_cs.cs_nffree++;
713 				j++;
714 			}
715 			/*
716 			 * Lets rejoin a possible partially growed fragment.
717 			 */
718 			k = 0;
719 			while (isset(cg_blksfree(&acg), i) &&
720 			    (i >= rounddown(osblock.fs_size - cbase,
721 			    sblock.fs_frag))) {
722 				i--;
723 				k++;
724 			}
725 			if (k)
726 				acg.cg_frsum[k]--;
727 			acg.cg_frsum[k + j]++;
728 		}
729 	}
730 
731 	/*
732 	 * Handle all new complete blocks here.
733 	 */
734 	for (i = roundup(osblock.fs_size - cbase, sblock.fs_frag);
735 	    i + sblock.fs_frag <= dmax - cbase;	/* XXX <= or only < ? */
736 	    i += sblock.fs_frag) {
737 		j = i / sblock.fs_frag;
738 		setblock(&sblock, cg_blksfree(&acg), j);
739 		updclst(j);
740 		acg.cg_cs.cs_nbfree++;
741 	}
742 
743 	/*
744 	 * Handle the last new block if there are stll some new fragments left.
745 	 * Here we don't have to bother about the cluster summary or the even
746 	 * the rotational layout table.
747 	 */
748 	if (i < (dmax - cbase)) {
749 		acg.cg_frsum[dmax - cbase - i]++;
750 		for (; i < dmax - cbase; i++) {
751 			setbit(cg_blksfree(&acg), i);
752 			acg.cg_cs.cs_nffree++;
753 		}
754 	}
755 
756 	sblock.fs_cstotal.cs_nffree +=
757 	    (acg.cg_cs.cs_nffree - aocg.cg_cs.cs_nffree);
758 	sblock.fs_cstotal.cs_nbfree +=
759 	    (acg.cg_cs.cs_nbfree - aocg.cg_cs.cs_nbfree);
760 	/*
761 	 * The following statistics are not changed here:
762 	 *     sblock.fs_cstotal.cs_ndir
763 	 *     sblock.fs_cstotal.cs_nifree
764 	 * As the statistics for this cylinder group are ready, copy it to
765 	 * the summary information array.
766 	 */
767 	*cs = acg.cg_cs;
768 
769 	/*
770 	 * Write the updated "joining" cylinder group back to disk.
771 	 */
772 	cgckhash(&acg);
773 	wtfs(fsbtodb(&sblock, cgtod(&sblock, cylno)), (size_t)sblock.fs_cgsize,
774 	    (void *)&acg, fso, Nflag);
775 	DBG_PRINT0("jcg written\n");
776 	DBG_DUMP_CG(&sblock, "new joining cg", &acg);
777 
778 	DBG_LEAVE;
779 	return;
780 }
781 
782 /*
783  * Here we update the location of the cylinder summary. We have two possible
784  * ways of growing the cylinder summary:
785  * (1)	We can try to grow the summary in the current location, and relocate
786  *	possibly used blocks within the current cylinder group.
787  * (2)	Alternatively we can relocate the whole cylinder summary to the first
788  *	new completely empty cylinder group. Once the cylinder summary is no
789  *	longer in the beginning of the first cylinder group you should never
790  *	use a version of fsck which is not aware of the possibility to have
791  *	this structure in a non standard place.
792  * Option (2) is considered to be less intrusive to the structure of the file-
793  * system, so that's the one being used.
794  */
795 static void
796 updcsloc(time_t modtime, int fsi, int fso, unsigned int Nflag)
797 {
798 	DBG_FUNC("updcsloc")
799 	struct csum *cs;
800 	int ocscg, ncscg;
801 	ufs2_daddr_t d;
802 	int lcs = 0;
803 	int block;
804 
805 	DBG_ENTER;
806 
807 	if (howmany(sblock.fs_cssize, sblock.fs_fsize) ==
808 	    howmany(osblock.fs_cssize, osblock.fs_fsize)) {
809 		/*
810 		 * No new fragment needed.
811 		 */
812 		DBG_LEAVE;
813 		return;
814 	}
815 	/* Adjust fs_dsize by added summary blocks */
816 	sblock.fs_dsize -= howmany(sblock.fs_cssize, sblock.fs_fsize) -
817 	    howmany(osblock.fs_cssize, osblock.fs_fsize);
818 	sblock.fs_old_dsize = sblock.fs_dsize;
819 	ocscg = dtog(&osblock, osblock.fs_csaddr);
820 	cs = fscs + ocscg;
821 
822 	/*
823 	 * Read original cylinder group from disk, and make a copy.
824 	 * XXX	If Nflag is set in some very rare cases we now miss
825 	 *	some changes done in updjcg by reading the unmodified
826 	 *	block from disk.
827 	 */
828 	rdfs(fsbtodb(&osblock, cgtod(&osblock, ocscg)),
829 	    (size_t)osblock.fs_cgsize, (void *)&aocg, fsi);
830 	DBG_PRINT0("oscg read\n");
831 	DBG_DUMP_CG(&sblock, "old summary cg", &aocg);
832 
833 	memcpy((void *)&cgun1, (void *)&cgun2, sizeof(cgun2));
834 
835 	/*
836 	 * Touch the cylinder group, set up local variables needed later
837 	 * and update the superblock.
838 	 */
839 	acg.cg_time = modtime;
840 
841 	/*
842 	 * XXX	In the case of having active snapshots we may need much more
843 	 *	blocks for the copy on write. We need each block twice, and
844 	 *	also up to 8*3 blocks for indirect blocks for all possible
845 	 *	references.
846 	 */
847 	/*
848 	 * There is not enough space in the old cylinder group to
849 	 * relocate all blocks as needed, so we relocate the whole
850 	 * cylinder group summary to a new group. We try to use the
851 	 * first complete new cylinder group just created. Within the
852 	 * cylinder group we align the area immediately after the
853 	 * cylinder group information location in order to be as
854 	 * close as possible to the original implementation of ffs.
855 	 *
856 	 * First we have to make sure we'll find enough space in the
857 	 * new cylinder group. If not, then we currently give up.
858 	 * We start with freeing everything which was used by the
859 	 * fragments of the old cylinder summary in the current group.
860 	 * Now we write back the group meta data, read in the needed
861 	 * meta data from the new cylinder group, and start allocating
862 	 * within that group. Here we can assume, the group to be
863 	 * completely empty. Which makes the handling of fragments and
864 	 * clusters a lot easier.
865 	 */
866 	DBG_TRC;
867 	if (sblock.fs_ncg - osblock.fs_ncg < 2)
868 		errx(2, "panic: not enough space");
869 
870 	/*
871 	 * Point "d" to the first fragment not used by the cylinder
872 	 * summary.
873 	 */
874 	d = osblock.fs_csaddr + (osblock.fs_cssize / osblock.fs_fsize);
875 
876 	/*
877 	 * Set up last cluster size ("lcs") already here. Calculate
878 	 * the size for the trailing cluster just behind where "d"
879 	 * points to.
880 	 */
881 	if (sblock.fs_contigsumsize > 0) {
882 		for (block = howmany(d % sblock.fs_fpg, sblock.fs_frag),
883 		    lcs = 0; lcs < sblock.fs_contigsumsize; block++, lcs++) {
884 			if (isclr(cg_clustersfree(&acg), block))
885 				break;
886 		}
887 	}
888 
889 	/*
890 	 * Point "d" to the last frag used by the cylinder summary.
891 	 */
892 	d--;
893 
894 	DBG_PRINT1("d=%jd\n", (intmax_t)d);
895 	if ((d + 1) % sblock.fs_frag) {
896 		/*
897 		 * The end of the cylinder summary is not a complete
898 		 * block.
899 		 */
900 		DBG_TRC;
901 		frag_adjust(d % sblock.fs_fpg, -1);
902 		for (; (d + 1) % sblock.fs_frag; d--) {
903 			DBG_PRINT1("d=%jd\n", (intmax_t)d);
904 			setbit(cg_blksfree(&acg), d % sblock.fs_fpg);
905 			acg.cg_cs.cs_nffree++;
906 			sblock.fs_cstotal.cs_nffree++;
907 		}
908 		/*
909 		 * Point "d" to the last fragment of the last
910 		 * (incomplete) block of the cylinder summary.
911 		 */
912 		d++;
913 		frag_adjust(d % sblock.fs_fpg, 1);
914 
915 		if (isblock(&sblock, cg_blksfree(&acg),
916 		    (d % sblock.fs_fpg) / sblock.fs_frag)) {
917 			DBG_PRINT1("d=%jd\n", (intmax_t)d);
918 			acg.cg_cs.cs_nffree -= sblock.fs_frag;
919 			acg.cg_cs.cs_nbfree++;
920 			sblock.fs_cstotal.cs_nffree -= sblock.fs_frag;
921 			sblock.fs_cstotal.cs_nbfree++;
922 			if (sblock.fs_contigsumsize > 0) {
923 				setbit(cg_clustersfree(&acg),
924 				    (d % sblock.fs_fpg) / sblock.fs_frag);
925 				if (lcs < sblock.fs_contigsumsize) {
926 					if (lcs)
927 						cg_clustersum(&acg)[lcs]--;
928 					lcs++;
929 					cg_clustersum(&acg)[lcs]++;
930 				}
931 			}
932 		}
933 		/*
934 		 * Point "d" to the first fragment of the block before
935 		 * the last incomplete block.
936 		 */
937 		d--;
938 	}
939 
940 	DBG_PRINT1("d=%jd\n", (intmax_t)d);
941 	for (d = rounddown(d, sblock.fs_frag); d >= osblock.fs_csaddr;
942 	    d -= sblock.fs_frag) {
943 		DBG_TRC;
944 		DBG_PRINT1("d=%jd\n", (intmax_t)d);
945 		setblock(&sblock, cg_blksfree(&acg),
946 		    (d % sblock.fs_fpg) / sblock.fs_frag);
947 		acg.cg_cs.cs_nbfree++;
948 		sblock.fs_cstotal.cs_nbfree++;
949 		if (sblock.fs_contigsumsize > 0) {
950 			setbit(cg_clustersfree(&acg),
951 			    (d % sblock.fs_fpg) / sblock.fs_frag);
952 			/*
953 			 * The last cluster size is already set up.
954 			 */
955 			if (lcs < sblock.fs_contigsumsize) {
956 				if (lcs)
957 					cg_clustersum(&acg)[lcs]--;
958 				lcs++;
959 				cg_clustersum(&acg)[lcs]++;
960 			}
961 		}
962 	}
963 	*cs = acg.cg_cs;
964 
965 	/*
966 	 * Now write the former cylinder group containing the cylinder
967 	 * summary back to disk.
968 	 */
969 	cgckhash(&acg);
970 	wtfs(fsbtodb(&sblock, cgtod(&sblock, ocscg)),
971 	    (size_t)sblock.fs_cgsize, (void *)&acg, fso, Nflag);
972 	DBG_PRINT0("oscg written\n");
973 	DBG_DUMP_CG(&sblock, "old summary cg", &acg);
974 
975 	/*
976 	 * Find the beginning of the new cylinder group containing the
977 	 * cylinder summary.
978 	 */
979 	sblock.fs_csaddr = cgdmin(&sblock, osblock.fs_ncg);
980 	ncscg = dtog(&sblock, sblock.fs_csaddr);
981 	cs = fscs + ncscg;
982 
983 	/*
984 	 * If Nflag is specified, we would now read random data instead
985 	 * of an empty cg structure from disk. So we can't simulate that
986 	 * part for now.
987 	 */
988 	if (Nflag) {
989 		DBG_PRINT0("nscg update skipped\n");
990 		DBG_LEAVE;
991 		return;
992 	}
993 
994 	/*
995 	 * Read the future cylinder group containing the cylinder
996 	 * summary from disk, and make a copy.
997 	 */
998 	rdfs(fsbtodb(&sblock, cgtod(&sblock, ncscg)),
999 	    (size_t)sblock.fs_cgsize, (void *)&aocg, fsi);
1000 	DBG_PRINT0("nscg read\n");
1001 	DBG_DUMP_CG(&sblock, "new summary cg", &aocg);
1002 
1003 	memcpy((void *)&cgun1, (void *)&cgun2, sizeof(cgun2));
1004 
1005 	/*
1006 	 * Allocate all complete blocks used by the new cylinder
1007 	 * summary.
1008 	 */
1009 	for (d = sblock.fs_csaddr; d + sblock.fs_frag <=
1010 	    sblock.fs_csaddr + (sblock.fs_cssize / sblock.fs_fsize);
1011 	    d += sblock.fs_frag) {
1012 		clrblock(&sblock, cg_blksfree(&acg),
1013 		    (d % sblock.fs_fpg) / sblock.fs_frag);
1014 		acg.cg_cs.cs_nbfree--;
1015 		sblock.fs_cstotal.cs_nbfree--;
1016 		if (sblock.fs_contigsumsize > 0) {
1017 			clrbit(cg_clustersfree(&acg),
1018 			    (d % sblock.fs_fpg) / sblock.fs_frag);
1019 		}
1020 	}
1021 
1022 	/*
1023 	 * Allocate all fragments used by the cylinder summary in the
1024 	 * last block.
1025 	 */
1026 	if (d < sblock.fs_csaddr + (sblock.fs_cssize / sblock.fs_fsize)) {
1027 		for (; d - sblock.fs_csaddr <
1028 		    sblock.fs_cssize/sblock.fs_fsize; d++) {
1029 			clrbit(cg_blksfree(&acg), d % sblock.fs_fpg);
1030 			acg.cg_cs.cs_nffree--;
1031 			sblock.fs_cstotal.cs_nffree--;
1032 		}
1033 		acg.cg_cs.cs_nbfree--;
1034 		acg.cg_cs.cs_nffree += sblock.fs_frag;
1035 		sblock.fs_cstotal.cs_nbfree--;
1036 		sblock.fs_cstotal.cs_nffree += sblock.fs_frag;
1037 		if (sblock.fs_contigsumsize > 0)
1038 			clrbit(cg_clustersfree(&acg),
1039 			    (d % sblock.fs_fpg) / sblock.fs_frag);
1040 
1041 		frag_adjust(d % sblock.fs_fpg, 1);
1042 	}
1043 	/*
1044 	 * XXX	Handle the cluster statistics here in the case this
1045 	 *	cylinder group is now almost full, and the remaining
1046 	 *	space is less then the maximum cluster size. This is
1047 	 *	probably not needed, as you would hardly find a file
1048 	 *	system which has only MAXCSBUFS+FS_MAXCONTIG of free
1049 	 *	space right behind the cylinder group information in
1050 	 *	any new cylinder group.
1051 	 */
1052 
1053 	/*
1054 	 * Update our statistics in the cylinder summary.
1055 	 */
1056 	*cs = acg.cg_cs;
1057 
1058 	/*
1059 	 * Write the new cylinder group containing the cylinder summary
1060 	 * back to disk.
1061 	 */
1062 	cgckhash(&acg);
1063 	wtfs(fsbtodb(&sblock, cgtod(&sblock, ncscg)),
1064 	    (size_t)sblock.fs_cgsize, (void *)&acg, fso, Nflag);
1065 	DBG_PRINT0("nscg written\n");
1066 	DBG_DUMP_CG(&sblock, "new summary cg", &acg);
1067 
1068 	DBG_LEAVE;
1069 	return;
1070 }
1071 
1072 /*
1073  * Here we read some block(s) from disk.
1074  */
1075 static void
1076 rdfs(ufs2_daddr_t bno, size_t size, void *bf, int fsi)
1077 {
1078 	DBG_FUNC("rdfs")
1079 	ssize_t	n;
1080 
1081 	DBG_ENTER;
1082 
1083 	if (bno < 0)
1084 		err(32, "rdfs: attempting to read negative block number");
1085 	if (lseek(fsi, (off_t)bno * DEV_BSIZE, 0) < 0)
1086 		err(33, "rdfs: seek error: %jd", (intmax_t)bno);
1087 	n = read(fsi, bf, size);
1088 	if (n != (ssize_t)size)
1089 		err(34, "rdfs: read error: %jd", (intmax_t)bno);
1090 
1091 	DBG_LEAVE;
1092 	return;
1093 }
1094 
1095 /*
1096  * Here we write some block(s) to disk.
1097  */
1098 static void
1099 wtfs(ufs2_daddr_t bno, size_t size, void *bf, int fso, unsigned int Nflag)
1100 {
1101 	DBG_FUNC("wtfs")
1102 	ssize_t	n;
1103 
1104 	DBG_ENTER;
1105 
1106 	if (Nflag) {
1107 		DBG_LEAVE;
1108 		return;
1109 	}
1110 	if (lseek(fso, (off_t)bno * DEV_BSIZE, SEEK_SET) < 0)
1111 		err(35, "wtfs: seek error: %ld", (long)bno);
1112 	n = write(fso, bf, size);
1113 	if (n != (ssize_t)size)
1114 		err(36, "wtfs: write error: %ld", (long)bno);
1115 
1116 	DBG_LEAVE;
1117 	return;
1118 }
1119 
1120 /*
1121  * Here we check if all frags of a block are free. For more details again
1122  * please see the source of newfs(8), as this function is taken over almost
1123  * unchanged.
1124  */
1125 static int
1126 isblock(struct fs *fs, unsigned char *cp, int h)
1127 {
1128 	DBG_FUNC("isblock")
1129 	unsigned char mask;
1130 
1131 	DBG_ENTER;
1132 
1133 	switch (fs->fs_frag) {
1134 	case 8:
1135 		DBG_LEAVE;
1136 		return (cp[h] == 0xff);
1137 	case 4:
1138 		mask = 0x0f << ((h & 0x1) << 2);
1139 		DBG_LEAVE;
1140 		return ((cp[h >> 1] & mask) == mask);
1141 	case 2:
1142 		mask = 0x03 << ((h & 0x3) << 1);
1143 		DBG_LEAVE;
1144 		return ((cp[h >> 2] & mask) == mask);
1145 	case 1:
1146 		mask = 0x01 << (h & 0x7);
1147 		DBG_LEAVE;
1148 		return ((cp[h >> 3] & mask) == mask);
1149 	default:
1150 		fprintf(stderr, "isblock bad fs_frag %d\n", fs->fs_frag);
1151 		DBG_LEAVE;
1152 		return (0);
1153 	}
1154 }
1155 
1156 /*
1157  * Here we allocate a complete block in the block map. For more details again
1158  * please see the source of newfs(8), as this function is taken over almost
1159  * unchanged.
1160  */
1161 static void
1162 clrblock(struct fs *fs, unsigned char *cp, int h)
1163 {
1164 	DBG_FUNC("clrblock")
1165 
1166 	DBG_ENTER;
1167 
1168 	switch ((fs)->fs_frag) {
1169 	case 8:
1170 		cp[h] = 0;
1171 		break;
1172 	case 4:
1173 		cp[h >> 1] &= ~(0x0f << ((h & 0x1) << 2));
1174 		break;
1175 	case 2:
1176 		cp[h >> 2] &= ~(0x03 << ((h & 0x3) << 1));
1177 		break;
1178 	case 1:
1179 		cp[h >> 3] &= ~(0x01 << (h & 0x7));
1180 		break;
1181 	default:
1182 		warnx("clrblock bad fs_frag %d", fs->fs_frag);
1183 		break;
1184 	}
1185 
1186 	DBG_LEAVE;
1187 	return;
1188 }
1189 
1190 /*
1191  * Here we free a complete block in the free block map. For more details again
1192  * please see the source of newfs(8), as this function is taken over almost
1193  * unchanged.
1194  */
1195 static void
1196 setblock(struct fs *fs, unsigned char *cp, int h)
1197 {
1198 	DBG_FUNC("setblock")
1199 
1200 	DBG_ENTER;
1201 
1202 	switch (fs->fs_frag) {
1203 	case 8:
1204 		cp[h] = 0xff;
1205 		break;
1206 	case 4:
1207 		cp[h >> 1] |= (0x0f << ((h & 0x1) << 2));
1208 		break;
1209 	case 2:
1210 		cp[h >> 2] |= (0x03 << ((h & 0x3) << 1));
1211 		break;
1212 	case 1:
1213 		cp[h >> 3] |= (0x01 << (h & 0x7));
1214 		break;
1215 	default:
1216 		warnx("setblock bad fs_frag %d", fs->fs_frag);
1217 		break;
1218 	}
1219 
1220 	DBG_LEAVE;
1221 	return;
1222 }
1223 
1224 /*
1225  * Figure out how many lines our current terminal has. For more details again
1226  * please see the source of newfs(8), as this function is taken over almost
1227  * unchanged.
1228  */
1229 static int
1230 charsperline(void)
1231 {
1232 	DBG_FUNC("charsperline")
1233 	int columns;
1234 	char *cp;
1235 	struct winsize ws;
1236 
1237 	DBG_ENTER;
1238 
1239 	columns = 0;
1240 	if (ioctl(0, TIOCGWINSZ, &ws) != -1)
1241 		columns = ws.ws_col;
1242 	if (columns == 0 && (cp = getenv("COLUMNS")))
1243 		columns = atoi(cp);
1244 	if (columns == 0)
1245 		columns = 80;	/* last resort */
1246 
1247 	DBG_LEAVE;
1248 	return (columns);
1249 }
1250 
1251 static int
1252 is_dev(const char *name)
1253 {
1254 	struct stat devstat;
1255 
1256 	if (stat(name, &devstat) != 0)
1257 		return (0);
1258 	if (!S_ISCHR(devstat.st_mode))
1259 		return (0);
1260 	return (1);
1261 }
1262 
1263 static const char *
1264 getdev(const char *name, struct statfs *statfsp)
1265 {
1266 	static char device[MAXPATHLEN];
1267 	const char *cp;
1268 
1269 	if (is_dev(name))
1270 		return (name);
1271 
1272 	cp = strrchr(name, '/');
1273 	if (cp == NULL) {
1274 		snprintf(device, sizeof(device), "%s%s", _PATH_DEV, name);
1275 		if (is_dev(device))
1276 			return (device);
1277 	}
1278 
1279 	if (statfsp != NULL)
1280 		return (statfsp->f_mntfromname);
1281 
1282 	return (NULL);
1283 }
1284 
1285 /*
1286  * growfs(8) is a utility which allows to increase the size of an existing
1287  * ufs file system. Currently this can only be done on unmounted file system.
1288  * It recognizes some command line options to specify the new desired size,
1289  * and it does some basic checkings. The old file system size is determined
1290  * and after some more checks like we can really access the new last block
1291  * on the disk etc. we calculate the new parameters for the superblock. After
1292  * having done this we just call growfs() which will do the work.
1293  * We still have to provide support for snapshots. Therefore we first have to
1294  * understand what data structures are always replicated in the snapshot on
1295  * creation, for all other blocks we touch during our procedure, we have to
1296  * keep the old blocks unchanged somewhere available for the snapshots. If we
1297  * are lucky, then we only have to handle our blocks to be relocated in that
1298  * way.
1299  * Also we have to consider in what order we actually update the critical
1300  * data structures of the file system to make sure, that in case of a disaster
1301  * fsck(8) is still able to restore any lost data.
1302  * The foreseen last step then will be to provide for growing even mounted
1303  * file systems. There we have to extend the mount() system call to provide
1304  * userland access to the file system locking facility.
1305  */
1306 int
1307 main(int argc, char **argv)
1308 {
1309 	DBG_FUNC("main")
1310 	struct fs *fs;
1311 	const char *device;
1312 	struct statfs *statfsp;
1313 	uint64_t size = 0;
1314 	off_t mediasize;
1315 	int error, j, fsi, fso, ch, ret, Nflag = 0, yflag = 0;
1316 	char *p, reply[5], oldsizebuf[6], newsizebuf[6];
1317 	void *testbuf;
1318 
1319 	DBG_ENTER;
1320 
1321 	while ((ch = getopt(argc, argv, "Ns:vy")) != -1) {
1322 		switch(ch) {
1323 		case 'N':
1324 			Nflag = 1;
1325 			break;
1326 		case 's':
1327 			size = (off_t)strtoumax(optarg, &p, 0);
1328 			if (p == NULL || *p == '\0')
1329 				size *= DEV_BSIZE;
1330 			else if (*p == 'b' || *p == 'B')
1331 				; /* do nothing */
1332 			else if (*p == 'k' || *p == 'K')
1333 				size <<= 10;
1334 			else if (*p == 'm' || *p == 'M')
1335 				size <<= 20;
1336 			else if (*p == 'g' || *p == 'G')
1337 				size <<= 30;
1338 			else if (*p == 't' || *p == 'T') {
1339 				size <<= 30;
1340 				size <<= 10;
1341 			} else
1342 				errx(1, "unknown suffix on -s argument");
1343 			break;
1344 		case 'v': /* for compatibility to newfs */
1345 			break;
1346 		case 'y':
1347 			yflag = 1;
1348 			break;
1349 		case '?':
1350 			/* FALLTHROUGH */
1351 		default:
1352 			usage();
1353 		}
1354 	}
1355 	argc -= optind;
1356 	argv += optind;
1357 
1358 	if (argc != 1)
1359 		usage();
1360 
1361 	/*
1362 	 * Now try to guess the device name.
1363 	 */
1364 	statfsp = getmntpoint(*argv);
1365 	device = getdev(*argv, statfsp);
1366 	if (device == NULL)
1367 		errx(1, "cannot find special device for %s", *argv);
1368 
1369 	fsi = open(device, O_RDONLY);
1370 	if (fsi < 0)
1371 		err(1, "%s", device);
1372 
1373 	/*
1374 	 * Try to guess the slice size if not specified.
1375 	 */
1376 	if (ioctl(fsi, DIOCGMEDIASIZE, &mediasize) == -1)
1377 		err(1,"DIOCGMEDIASIZE");
1378 
1379 	/*
1380 	 * Check if that partition is suitable for growing a file system.
1381 	 */
1382 	if (mediasize < 1)
1383 		errx(1, "partition is unavailable");
1384 
1385 	/*
1386 	 * Read the current superblock, and take a backup.
1387 	 */
1388 	if ((ret = sbget(fsi, &fs, UFS_STDSB, 0)) != 0) {
1389 		switch (ret) {
1390 		case ENOENT:
1391 			errx(1, "superblock not recognized");
1392 		default:
1393 			errc(1, ret, "unable to read superblock");
1394 		}
1395 	}
1396 	/*
1397 	 * Check for filesystem that was unclean at mount time.
1398 	 */
1399 	if ((fs->fs_flags & (FS_UNCLEAN | FS_NEEDSFSCK)) != 0)
1400 		errx(1, "%s is not clean - run fsck.\n", *argv);
1401 	memcpy(&osblock, fs, fs->fs_sbsize);
1402 	free(fs);
1403 	memcpy((void *)&fsun1, (void *)&fsun2, osblock.fs_sbsize);
1404 
1405 	DBG_OPEN("/tmp/growfs.debug"); /* already here we need a superblock */
1406 	DBG_DUMP_FS(&sblock, "old sblock");
1407 
1408 	/*
1409 	 * Determine size to grow to. Default to the device size.
1410 	 */
1411 	if (size == 0)
1412 		size = mediasize;
1413 	else {
1414 		if (size > (uint64_t)mediasize) {
1415 			humanize_number(oldsizebuf, sizeof(oldsizebuf), size,
1416 			    "B", HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL);
1417 			humanize_number(newsizebuf, sizeof(newsizebuf),
1418 			    mediasize,
1419 			    "B", HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL);
1420 
1421 			errx(1, "requested size %s is larger "
1422 			    "than the available %s", oldsizebuf, newsizebuf);
1423 		}
1424 	}
1425 
1426 	/*
1427 	 * Make sure the new size is a multiple of fs_fsize; /dev/ufssuspend
1428 	 * only supports fragment-aligned IO requests.
1429 	 */
1430 	size -= size % osblock.fs_fsize;
1431 
1432 	if (size <= (uint64_t)(osblock.fs_size * osblock.fs_fsize)) {
1433 		humanize_number(oldsizebuf, sizeof(oldsizebuf),
1434 		    osblock.fs_size * osblock.fs_fsize,
1435 		    "B", HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL);
1436 		humanize_number(newsizebuf, sizeof(newsizebuf), size,
1437 		    "B", HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL);
1438 
1439 		if (size == (uint64_t)(osblock.fs_size * osblock.fs_fsize))
1440 			errx(0, "requested size %s is equal to the current "
1441 			    "filesystem size %s", newsizebuf, oldsizebuf);
1442 		errx(1, "requested size %s is smaller than the current "
1443 		   "filesystem size %s", newsizebuf, oldsizebuf);
1444 	}
1445 
1446 	sblock.fs_old_size = sblock.fs_size =
1447 	    dbtofsb(&osblock, size / DEV_BSIZE);
1448 	sblock.fs_providersize = dbtofsb(&osblock, mediasize / DEV_BSIZE);
1449 
1450 	/*
1451 	 * Are we really growing?
1452 	 */
1453 	if (osblock.fs_size >= sblock.fs_size) {
1454 		errx(1, "we are not growing (%jd->%jd)",
1455 		    (intmax_t)osblock.fs_size, (intmax_t)sblock.fs_size);
1456 	}
1457 
1458 	/*
1459 	 * Check if we find an active snapshot.
1460 	 */
1461 	if (yflag == 0) {
1462 		for (j = 0; j < FSMAXSNAP; j++) {
1463 			if (sblock.fs_snapinum[j]) {
1464 				errx(1, "active snapshot found in file system; "
1465 				    "please remove all snapshots before "
1466 				    "using growfs");
1467 			}
1468 			if (!sblock.fs_snapinum[j]) /* list is dense */
1469 				break;
1470 		}
1471 	}
1472 
1473 	if (yflag == 0 && Nflag == 0) {
1474 		if (statfsp != NULL && (statfsp->f_flags & MNT_RDONLY) == 0)
1475 			printf("Device is mounted read-write; resizing will "
1476 			    "result in temporary write suspension for %s.\n",
1477 			    statfsp->f_mntonname);
1478 		printf("It's strongly recommended to make a backup "
1479 		    "before growing the file system.\n"
1480 		    "OK to grow filesystem on %s", device);
1481 		if (statfsp != NULL)
1482 			printf(", mounted on %s,", statfsp->f_mntonname);
1483 		humanize_number(oldsizebuf, sizeof(oldsizebuf),
1484 		    osblock.fs_size * osblock.fs_fsize,
1485 		    "B", HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL);
1486 		humanize_number(newsizebuf, sizeof(newsizebuf),
1487 		    sblock.fs_size * sblock.fs_fsize,
1488 		    "B", HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL);
1489 		printf(" from %s to %s? [yes/no] ", oldsizebuf, newsizebuf);
1490 		fflush(stdout);
1491 		fgets(reply, (int)sizeof(reply), stdin);
1492 		if (strcasecmp(reply, "yes\n")){
1493 			printf("Response other than \"yes\"; aborting\n");
1494 			exit(0);
1495 		}
1496 	}
1497 
1498 	/*
1499 	 * Try to access our device for writing.  If it's not mounted,
1500 	 * or mounted read-only, simply open it; otherwise, use UFS
1501 	 * suspension mechanism.
1502 	 */
1503 	if (Nflag) {
1504 		fso = -1;
1505 	} else {
1506 		if (statfsp != NULL && (statfsp->f_flags & MNT_RDONLY) == 0) {
1507 			fso = open(_PATH_UFSSUSPEND, O_RDWR);
1508 			if (fso == -1)
1509 				err(1, "unable to open %s", _PATH_UFSSUSPEND);
1510 			error = ioctl(fso, UFSSUSPEND, &statfsp->f_fsid);
1511 			if (error != 0)
1512 				err(1, "UFSSUSPEND");
1513 		} else {
1514 			fso = open(device, O_WRONLY);
1515 			if (fso < 0)
1516 				err(1, "%s", device);
1517 		}
1518 	}
1519 
1520 	/*
1521 	 * Try to access our new last block in the file system.
1522 	 */
1523 	testbuf = malloc(sblock.fs_fsize);
1524 	if (testbuf == NULL)
1525 		err(1, "malloc");
1526 	rdfs((ufs2_daddr_t)((size - sblock.fs_fsize) / DEV_BSIZE),
1527 	    sblock.fs_fsize, testbuf, fsi);
1528 	wtfs((ufs2_daddr_t)((size - sblock.fs_fsize) / DEV_BSIZE),
1529 	    sblock.fs_fsize, testbuf, fso, Nflag);
1530 	free(testbuf);
1531 
1532 	/*
1533 	 * Now calculate new superblock values and check for reasonable
1534 	 * bound for new file system size:
1535 	 *     fs_size:    is derived from user input
1536 	 *     fs_dsize:   should get updated in the routines creating or
1537 	 *                 updating the cylinder groups on the fly
1538 	 *     fs_cstotal: should get updated in the routines creating or
1539 	 *                 updating the cylinder groups
1540 	 */
1541 
1542 	/*
1543 	 * Update the number of cylinders and cylinder groups in the file system.
1544 	 */
1545 	if (sblock.fs_magic == FS_UFS1_MAGIC) {
1546 		sblock.fs_old_ncyl =
1547 		    sblock.fs_size * sblock.fs_old_nspf / sblock.fs_old_spc;
1548 		if (sblock.fs_size * sblock.fs_old_nspf >
1549 		    sblock.fs_old_ncyl * sblock.fs_old_spc)
1550 			sblock.fs_old_ncyl++;
1551 	}
1552 	sblock.fs_ncg = howmany(sblock.fs_size, sblock.fs_fpg);
1553 
1554 	/*
1555 	 * Allocate last cylinder group only if there is enough room
1556 	 * for at least one data block.
1557 	 */
1558 	if (sblock.fs_size % sblock.fs_fpg != 0 &&
1559 	    sblock.fs_size <= cgdmin(&sblock, sblock.fs_ncg - 1)) {
1560 		humanize_number(oldsizebuf, sizeof(oldsizebuf),
1561 		    (sblock.fs_size % sblock.fs_fpg) * sblock.fs_fsize,
1562 		    "B", HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL);
1563 		warnx("no room to allocate last cylinder group; "
1564 		    "leaving %s unused", oldsizebuf);
1565 		sblock.fs_ncg--;
1566 		if (sblock.fs_magic == FS_UFS1_MAGIC)
1567 			sblock.fs_old_ncyl = sblock.fs_ncg * sblock.fs_old_cpg;
1568 		sblock.fs_old_size = sblock.fs_size =
1569 		    sblock.fs_ncg * sblock.fs_fpg;
1570 	}
1571 
1572 	/*
1573 	 * Update the space for the cylinder group summary information in the
1574 	 * respective cylinder group data area.
1575 	 */
1576 	sblock.fs_cssize =
1577 	    fragroundup(&sblock, sblock.fs_ncg * sizeof(struct csum));
1578 
1579 	if (osblock.fs_size >= sblock.fs_size)
1580 		errx(1, "not enough new space");
1581 
1582 	DBG_PRINT0("sblock calculated\n");
1583 
1584 	/*
1585 	 * Ok, everything prepared, so now let's do the tricks.
1586 	 */
1587 	growfs(fsi, fso, Nflag);
1588 
1589 	close(fsi);
1590 	if (fso > -1) {
1591 		if (statfsp != NULL && (statfsp->f_flags & MNT_RDONLY) == 0) {
1592 			error = ioctl(fso, UFSRESUME);
1593 			if (error != 0)
1594 				err(1, "UFSRESUME");
1595 		}
1596 		error = close(fso);
1597 		if (error != 0)
1598 			err(1, "close");
1599 		if (statfsp != NULL && (statfsp->f_flags & MNT_RDONLY) != 0 &&
1600 		    chkdoreload(statfsp, warn) != 0)
1601 			exit(9);
1602 	}
1603 
1604 	DBG_CLOSE;
1605 
1606 	DBG_LEAVE;
1607 	return (0);
1608 }
1609 
1610 /*
1611  * Dump a line of usage.
1612  */
1613 static void
1614 usage(void)
1615 {
1616 	DBG_FUNC("usage")
1617 
1618 	DBG_ENTER;
1619 
1620 	fprintf(stderr, "usage: growfs [-Ny] [-s size] special | filesystem\n");
1621 
1622 	DBG_LEAVE;
1623 	exit(1);
1624 }
1625 
1626 /*
1627  * This updates most parameters and the bitmap related to cluster. We have to
1628  * assume that sblock, osblock, acg are set up.
1629  */
1630 static void
1631 updclst(int block)
1632 {
1633 	DBG_FUNC("updclst")
1634 	static int lcs = 0;
1635 
1636 	DBG_ENTER;
1637 
1638 	if (sblock.fs_contigsumsize < 1) /* no clustering */
1639 		return;
1640 	/*
1641 	 * update cluster allocation map
1642 	 */
1643 	setbit(cg_clustersfree(&acg), block);
1644 
1645 	/*
1646 	 * update cluster summary table
1647 	 */
1648 	if (!lcs) {
1649 		/*
1650 		 * calculate size for the trailing cluster
1651 		 */
1652 		for (block--; lcs < sblock.fs_contigsumsize; block--, lcs++ ) {
1653 			if (isclr(cg_clustersfree(&acg), block))
1654 				break;
1655 		}
1656 	}
1657 	if (lcs < sblock.fs_contigsumsize) {
1658 		if (lcs)
1659 			cg_clustersum(&acg)[lcs]--;
1660 		lcs++;
1661 		cg_clustersum(&acg)[lcs]++;
1662 	}
1663 
1664 	DBG_LEAVE;
1665 	return;
1666 }
1667 
1668 /*
1669  * Calculate the check-hash of the cylinder group.
1670  */
1671 static void
1672 cgckhash(struct cg *cgp)
1673 {
1674 
1675 	if ((sblock.fs_metackhash & CK_CYLGRP) == 0)
1676 		return;
1677 	cgp->cg_ckhash = 0;
1678 	cgp->cg_ckhash = calculate_crc32c(~0L, (void *)cgp, sblock.fs_cgsize);
1679 }
1680