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