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