growfs.c revision 203835
1/*
2 * Copyright (c) 2000 Christoph Herrmann, Thomas-Henning von Kamptz
3 * Copyright (c) 1980, 1989, 1993 The Regents of the University of California.
4 * All rights reserved.
5 *
6 * This code is derived from software contributed to Berkeley by
7 * Christoph Herrmann and Thomas-Henning von Kamptz, Munich and Frankfurt.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 *    notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 *    notice, this list of conditions and the following disclaimer in the
16 *    documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 *    must display the following acknowledgment:
19 *      This product includes software developed by the University of
20 *      California, Berkeley and its contributors, as well as Christoph
21 *      Herrmann and Thomas-Henning von Kamptz.
22 * 4. Neither the name of the University nor the names of its contributors
23 *    may be used to endorse or promote products derived from this software
24 *    without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
37 *
38 * $TSHeader: src/sbin/growfs/growfs.c,v 1.5 2000/12/12 19:31:00 tomsoft Exp $
39 *
40 */
41
42#ifndef lint
43static const char copyright[] =
44"@(#) Copyright (c) 2000 Christoph Herrmann, Thomas-Henning von Kamptz\n\
45Copyright (c) 1980, 1989, 1993 The Regents of the University of California.\n\
46All rights reserved.\n";
47#endif /* not lint */
48
49#include <sys/cdefs.h>
50__FBSDID("$FreeBSD: head/sbin/growfs/growfs.c 203835 2010-02-13 16:22:08Z gavin $");
51
52/* ********************************************************** INCLUDES ***** */
53#include <sys/param.h>
54#include <sys/disklabel.h>
55#include <sys/ioctl.h>
56#include <sys/stat.h>
57#include <sys/disk.h>
58
59#include <stdio.h>
60#include <paths.h>
61#include <ctype.h>
62#include <err.h>
63#include <fcntl.h>
64#include <limits.h>
65#include <stdlib.h>
66#include <stdint.h>
67#include <string.h>
68#include <time.h>
69#include <unistd.h>
70#include <ufs/ufs/dinode.h>
71#include <ufs/ffs/fs.h>
72
73#include "debug.h"
74
75/* *************************************************** GLOBALS & TYPES ***** */
76#ifdef FS_DEBUG
77int	_dbg_lvl_ = (DL_INFO);	/* DL_TRC */
78#endif /* FS_DEBUG */
79
80static union {
81	struct fs	fs;
82	char	pad[SBLOCKSIZE];
83} fsun1, fsun2;
84#define	sblock	fsun1.fs	/* the new superblock */
85#define	osblock	fsun2.fs	/* the old superblock */
86
87/*
88 * Possible superblock locations ordered from most to least likely.
89 */
90static int sblock_try[] = SBLOCKSEARCH;
91static ufs2_daddr_t sblockloc;
92
93static union {
94	struct cg	cg;
95	char	pad[MAXBSIZE];
96} cgun1, cgun2;
97#define	acg	cgun1.cg	/* a cylinder cgroup (new) */
98#define	aocg	cgun2.cg	/* an old cylinder group */
99
100static char	ablk[MAXBSIZE];	/* a block */
101
102static struct csum	*fscs;	/* cylinder summary */
103
104union dinode {
105	struct ufs1_dinode dp1;
106	struct ufs2_dinode dp2;
107};
108#define	DIP(dp, field) \
109	((sblock.fs_magic == FS_UFS1_MAGIC) ? \
110	(uint32_t)(dp)->dp1.field : (dp)->dp2.field)
111#define	DIP_SET(dp, field, val) do { \
112	if (sblock.fs_magic == FS_UFS1_MAGIC) \
113		(dp)->dp1.field = (val); \
114	else \
115		(dp)->dp2.field = (val); \
116	} while (0)
117static ufs2_daddr_t 	inoblk;			/* inode block address */
118static char		inobuf[MAXBSIZE];	/* inode block */
119ino_t			maxino;			/* last valid inode */
120static int		unlabeled;     /* unlabeled partition, e.g. vinum volume etc. */
121
122/*
123 * An array of elements of type struct gfs_bpp describes all blocks to
124 * be relocated in order to free the space needed for the cylinder group
125 * summary for all cylinder groups located in the first cylinder group.
126 */
127struct gfs_bpp {
128	ufs2_daddr_t	old;		/* old block number */
129	ufs2_daddr_t	new;		/* new block number */
130#define GFS_FL_FIRST	1
131#define GFS_FL_LAST	2
132	unsigned int	flags;	/* special handling required */
133	int	found;		/* how many references were updated */
134};
135
136/* ******************************************************** PROTOTYPES ***** */
137static void	growfs(int, int, unsigned int);
138static void	rdfs(ufs2_daddr_t, size_t, void *, int);
139static void	wtfs(ufs2_daddr_t, size_t, void *, int, unsigned int);
140static ufs2_daddr_t alloc(void);
141static int	charsperline(void);
142static void	usage(void);
143static int	isblock(struct fs *, unsigned char *, int);
144static void	clrblock(struct fs *, unsigned char *, int);
145static void	setblock(struct fs *, unsigned char *, int);
146static void	initcg(int, time_t, int, unsigned int);
147static void	updjcg(int, time_t, int, int, unsigned int);
148static void	updcsloc(time_t, int, int, unsigned int);
149static struct disklabel	*get_disklabel(int);
150static void	return_disklabel(int, struct disklabel *, unsigned int);
151static union dinode *ginode(ino_t, int, int);
152static void	frag_adjust(ufs2_daddr_t, int);
153static int	cond_bl_upd(ufs2_daddr_t *, struct gfs_bpp *, int, int,
154		    unsigned int);
155static void	updclst(int);
156static void	updrefs(int, ino_t, struct gfs_bpp *, int, int, unsigned int);
157static void	indirchk(ufs_lbn_t, ufs_lbn_t, ufs2_daddr_t, ufs_lbn_t,
158		    struct gfs_bpp *, int, int, unsigned int);
159static void	get_dev_size(int, int *);
160
161/* ************************************************************ growfs ***** */
162/*
163 * Here we actually start growing the file system. We basically read the
164 * cylinder summary from the first cylinder group as we want to update
165 * this on the fly during our various operations. First we handle the
166 * changes in the former last cylinder group. Afterwards we create all new
167 * cylinder groups.  Now we handle the cylinder group containing the
168 * cylinder summary which might result in a relocation of the whole
169 * structure.  In the end we write back the updated cylinder summary, the
170 * new superblock, and slightly patched versions of the super block
171 * copies.
172 */
173static void
174growfs(int fsi, int fso, unsigned int Nflag)
175{
176	DBG_FUNC("growfs")
177	time_t	utime;
178	uint	cylno;
179	int	i, j, width;
180	char	tmpbuf[100];
181#ifdef FSIRAND
182	static int	randinit=0;
183
184	DBG_ENTER;
185
186	if (!randinit) {
187		randinit = 1;
188		srandomdev();
189	}
190#else /* not FSIRAND */
191
192	DBG_ENTER;
193
194#endif /* FSIRAND */
195	time(&utime);
196
197	/*
198	 * Get the cylinder summary into the memory.
199	 */
200	fscs = (struct csum *)calloc((size_t)1, (size_t)sblock.fs_cssize);
201	if(fscs == NULL) {
202		errx(1, "calloc failed");
203	}
204	for (i = 0; i < osblock.fs_cssize; i += osblock.fs_bsize) {
205		rdfs(fsbtodb(&osblock, osblock.fs_csaddr +
206		    numfrags(&osblock, i)), (size_t)MIN(osblock.fs_cssize - i,
207		    osblock.fs_bsize), (void *)(((char *)fscs)+i), fsi);
208	}
209
210#ifdef FS_DEBUG
211{
212	struct csum	*dbg_csp;
213	int	dbg_csc;
214	char	dbg_line[80];
215
216	dbg_csp=fscs;
217	for(dbg_csc=0; dbg_csc<osblock.fs_ncg; dbg_csc++) {
218		snprintf(dbg_line, sizeof(dbg_line),
219		    "%d. old csum in old location", dbg_csc);
220		DBG_DUMP_CSUM(&osblock,
221		    dbg_line,
222		    dbg_csp++);
223	}
224}
225#endif /* FS_DEBUG */
226	DBG_PRINT0("fscs read\n");
227
228	/*
229	 * Do all needed changes in the former last cylinder group.
230	 */
231	updjcg(osblock.fs_ncg-1, utime, fsi, fso, Nflag);
232
233	/*
234	 * Dump out summary information about file system.
235	 */
236#	define B2MBFACTOR (1 / (1024.0 * 1024.0))
237	printf("growfs: %.1fMB (%jd sectors) block size %d, fragment size %d\n",
238	    (float)sblock.fs_size * sblock.fs_fsize * B2MBFACTOR,
239	    (intmax_t)fsbtodb(&sblock, sblock.fs_size), sblock.fs_bsize,
240	    sblock.fs_fsize);
241	printf("\tusing %d cylinder groups of %.2fMB, %d blks, %d inodes.\n",
242	    sblock.fs_ncg, (float)sblock.fs_fpg * sblock.fs_fsize * B2MBFACTOR,
243	    sblock.fs_fpg / sblock.fs_frag, sblock.fs_ipg);
244	if (sblock.fs_flags & FS_DOSOFTDEP)
245		printf("\twith soft updates\n");
246#	undef B2MBFACTOR
247
248	/*
249	 * Now build the cylinders group blocks and
250	 * then print out indices of cylinder groups.
251	 */
252	printf("super-block backups (for fsck -b #) at:\n");
253	i = 0;
254	width = charsperline();
255
256	/*
257	 * Iterate for only the new cylinder groups.
258	 */
259	for (cylno = osblock.fs_ncg; cylno < sblock.fs_ncg; cylno++) {
260		initcg(cylno, utime, fso, Nflag);
261		j = sprintf(tmpbuf, " %jd%s",
262		    (intmax_t)fsbtodb(&sblock, cgsblock(&sblock, cylno)),
263		    cylno < (sblock.fs_ncg-1) ? "," : "" );
264		if (i + j >= width) {
265			printf("\n");
266			i = 0;
267		}
268		i += j;
269		printf("%s", tmpbuf);
270		fflush(stdout);
271	}
272	printf("\n");
273
274	/*
275	 * Do all needed changes in the first cylinder group.
276	 * allocate blocks in new location
277	 */
278	updcsloc(utime, fsi, fso, Nflag);
279
280	/*
281	 * Now write the cylinder summary back to disk.
282	 */
283	for (i = 0; i < sblock.fs_cssize; i += sblock.fs_bsize) {
284		wtfs(fsbtodb(&sblock, sblock.fs_csaddr + numfrags(&sblock, i)),
285		    (size_t)MIN(sblock.fs_cssize - i, sblock.fs_bsize),
286		    (void *)(((char *)fscs) + i), fso, Nflag);
287	}
288	DBG_PRINT0("fscs written\n");
289
290#ifdef FS_DEBUG
291{
292	struct csum	*dbg_csp;
293	int	dbg_csc;
294	char	dbg_line[80];
295
296	dbg_csp=fscs;
297	for(dbg_csc=0; dbg_csc<sblock.fs_ncg; dbg_csc++) {
298		snprintf(dbg_line, sizeof(dbg_line),
299		    "%d. new csum in new location", dbg_csc);
300		DBG_DUMP_CSUM(&sblock,
301		    dbg_line,
302		    dbg_csp++);
303	}
304}
305#endif /* FS_DEBUG */
306
307	/*
308	 * Now write the new superblock back to disk.
309	 */
310	sblock.fs_time = utime;
311	wtfs(sblockloc, (size_t)SBLOCKSIZE, (void *)&sblock, fso, Nflag);
312	DBG_PRINT0("sblock written\n");
313	DBG_DUMP_FS(&sblock,
314	    "new initial sblock");
315
316	/*
317	 * Clean up the dynamic fields in our superblock copies.
318	 */
319	sblock.fs_fmod = 0;
320	sblock.fs_clean = 1;
321	sblock.fs_ronly = 0;
322	sblock.fs_cgrotor = 0;
323	sblock.fs_state = 0;
324	memset((void *)&sblock.fs_fsmnt, 0, sizeof(sblock.fs_fsmnt));
325	sblock.fs_flags &= FS_DOSOFTDEP;
326
327	/*
328	 * XXX
329	 * The following fields are currently distributed from the superblock
330	 * to the copies:
331	 *     fs_minfree
332	 *     fs_rotdelay
333	 *     fs_maxcontig
334	 *     fs_maxbpg
335	 *     fs_minfree,
336	 *     fs_optim
337	 *     fs_flags regarding SOFTPDATES
338	 *
339	 * We probably should rather change the summary for the cylinder group
340	 * statistics here to the value of what would be in there, if the file
341	 * system were created initially with the new size. Therefor we still
342	 * need to find an easy way of calculating that.
343	 * Possibly we can try to read the first superblock copy and apply the
344	 * "diffed" stats between the old and new superblock by still copying
345	 * certain parameters onto that.
346	 */
347
348	/*
349	 * Write out the duplicate super blocks.
350	 */
351	for (cylno = 0; cylno < sblock.fs_ncg; cylno++) {
352		wtfs(fsbtodb(&sblock, cgsblock(&sblock, cylno)),
353		    (size_t)SBLOCKSIZE, (void *)&sblock, fso, Nflag);
354	}
355	DBG_PRINT0("sblock copies written\n");
356	DBG_DUMP_FS(&sblock,
357	    "new other sblocks");
358
359	DBG_LEAVE;
360	return;
361}
362
363/* ************************************************************ initcg ***** */
364/*
365 * This creates a new cylinder group structure, for more details please see
366 * the source of newfs(8), as this function is taken over almost unchanged.
367 * As this is never called for the first cylinder group, the special
368 * provisions for that case are removed here.
369 */
370static void
371initcg(int cylno, time_t utime, int fso, unsigned int Nflag)
372{
373	DBG_FUNC("initcg")
374	static void *iobuf;
375	long blkno, start;
376	ufs2_daddr_t i, cbase, dmax;
377	struct ufs1_dinode *dp1;
378	struct csum *cs;
379	uint d, dupper, dlower;
380
381	if (iobuf == NULL && (iobuf = malloc(sblock.fs_bsize)) == NULL) {
382		errx(37, "panic: cannot allocate I/O buffer");
383	}
384	/*
385	 * Determine block bounds for cylinder group.
386	 * Allow space for super block summary information in first
387	 * cylinder group.
388	 */
389	cbase = cgbase(&sblock, cylno);
390	dmax = cbase + sblock.fs_fpg;
391	if (dmax > sblock.fs_size)
392		dmax = sblock.fs_size;
393	dlower = cgsblock(&sblock, cylno) - cbase;
394	dupper = cgdmin(&sblock, cylno) - cbase;
395	if (cylno == 0)	/* XXX fscs may be relocated */
396		dupper += howmany(sblock.fs_cssize, sblock.fs_fsize);
397	cs = &fscs[cylno];
398	memset(&acg, 0, sblock.fs_cgsize);
399	/*
400	 * Note that we do not set cg_initediblk at all.
401	 * In this extension of a previous filesystem
402	 * we have no inodes initialized for the cylinder
403	 * group at all. The first access to that cylinder
404	 * group will do the correct initialization.
405	 */
406	acg.cg_time = utime;
407	acg.cg_magic = CG_MAGIC;
408	acg.cg_cgx = cylno;
409	acg.cg_niblk = sblock.fs_ipg;
410	acg.cg_ndblk = dmax - cbase;
411	if (sblock.fs_contigsumsize > 0)
412		acg.cg_nclusterblks = acg.cg_ndblk / sblock.fs_frag;
413	start = &acg.cg_space[0] - (u_char *)(&acg.cg_firstfield);
414	if (sblock.fs_magic == FS_UFS2_MAGIC) {
415		acg.cg_iusedoff = start;
416	} else {
417		acg.cg_old_ncyl = sblock.fs_old_cpg;
418		acg.cg_old_time = acg.cg_time;
419		acg.cg_time = 0;
420		acg.cg_old_niblk = acg.cg_niblk;
421		acg.cg_niblk = 0;
422		acg.cg_old_btotoff = start;
423		acg.cg_old_boff = acg.cg_old_btotoff +
424		    sblock.fs_old_cpg * sizeof(int32_t);
425		acg.cg_iusedoff = acg.cg_old_boff +
426		    sblock.fs_old_cpg * sizeof(u_int16_t);
427	}
428	acg.cg_freeoff = acg.cg_iusedoff + howmany(sblock.fs_ipg, CHAR_BIT);
429	acg.cg_nextfreeoff = acg.cg_freeoff + howmany(sblock.fs_fpg, CHAR_BIT);
430	if (sblock.fs_contigsumsize > 0) {
431		acg.cg_clustersumoff =
432		    roundup(acg.cg_nextfreeoff, sizeof(u_int32_t));
433		acg.cg_clustersumoff -= sizeof(u_int32_t);
434		acg.cg_clusteroff = acg.cg_clustersumoff +
435		    (sblock.fs_contigsumsize + 1) * sizeof(u_int32_t);
436		acg.cg_nextfreeoff = acg.cg_clusteroff +
437		    howmany(fragstoblks(&sblock, sblock.fs_fpg), CHAR_BIT);
438	}
439	if (acg.cg_nextfreeoff > (unsigned)sblock.fs_cgsize) {
440		/*
441		 * This should never happen as we would have had that panic
442		 * already on file system creation
443		 */
444		errx(37, "panic: cylinder group too big");
445	}
446	acg.cg_cs.cs_nifree += sblock.fs_ipg;
447	if (cylno == 0)
448		for (i = 0; i < ROOTINO; i++) {
449			setbit(cg_inosused(&acg), i);
450			acg.cg_cs.cs_nifree--;
451		}
452	/*
453	 * For the old file system, we have to initialize all the inodes.
454	 */
455	if (sblock.fs_magic == FS_UFS1_MAGIC) {
456		bzero(iobuf, sblock.fs_bsize);
457		for (i = 0; i < sblock.fs_ipg / INOPF(&sblock);
458		     i += sblock.fs_frag) {
459			dp1 = (struct ufs1_dinode *)iobuf;
460#ifdef FSIRAND
461			for (j = 0; j < INOPB(&sblock); j++) {
462				dp1->di_gen = random();
463				dp1++;
464			}
465#endif
466			wtfs(fsbtodb(&sblock, cgimin(&sblock, cylno) + i),
467			    sblock.fs_bsize, iobuf, fso, Nflag);
468		}
469	}
470	if (cylno > 0) {
471		/*
472		 * In cylno 0, beginning space is reserved
473		 * for boot and super blocks.
474		 */
475		for (d = 0; d < dlower; d += sblock.fs_frag) {
476			blkno = d / sblock.fs_frag;
477			setblock(&sblock, cg_blksfree(&acg), blkno);
478			if (sblock.fs_contigsumsize > 0)
479				setbit(cg_clustersfree(&acg), blkno);
480			acg.cg_cs.cs_nbfree++;
481		}
482		sblock.fs_dsize += dlower;
483	}
484	sblock.fs_dsize += acg.cg_ndblk - dupper;
485	if ((i = dupper % sblock.fs_frag)) {
486		acg.cg_frsum[sblock.fs_frag - i]++;
487		for (d = dupper + sblock.fs_frag - i; dupper < d; dupper++) {
488			setbit(cg_blksfree(&acg), dupper);
489			acg.cg_cs.cs_nffree++;
490		}
491	}
492	for (d = dupper; d + sblock.fs_frag <= acg.cg_ndblk;
493	     d += sblock.fs_frag) {
494		blkno = d / sblock.fs_frag;
495		setblock(&sblock, cg_blksfree(&acg), blkno);
496		if (sblock.fs_contigsumsize > 0)
497			setbit(cg_clustersfree(&acg), blkno);
498		acg.cg_cs.cs_nbfree++;
499	}
500	if (d < acg.cg_ndblk) {
501		acg.cg_frsum[acg.cg_ndblk - d]++;
502		for (; d < acg.cg_ndblk; d++) {
503			setbit(cg_blksfree(&acg), d);
504			acg.cg_cs.cs_nffree++;
505		}
506	}
507	if (sblock.fs_contigsumsize > 0) {
508		int32_t *sump = cg_clustersum(&acg);
509		u_char *mapp = cg_clustersfree(&acg);
510		int map = *mapp++;
511		int bit = 1;
512		int run = 0;
513
514		for (i = 0; i < acg.cg_nclusterblks; i++) {
515			if ((map & bit) != 0)
516				run++;
517			else if (run != 0) {
518				if (run > sblock.fs_contigsumsize)
519					run = sblock.fs_contigsumsize;
520				sump[run]++;
521				run = 0;
522			}
523			if ((i & (CHAR_BIT - 1)) != CHAR_BIT - 1)
524				bit <<= 1;
525			else {
526				map = *mapp++;
527				bit = 1;
528			}
529		}
530		if (run != 0) {
531			if (run > sblock.fs_contigsumsize)
532				run = sblock.fs_contigsumsize;
533			sump[run]++;
534		}
535	}
536	sblock.fs_cstotal.cs_ndir += acg.cg_cs.cs_ndir;
537	sblock.fs_cstotal.cs_nffree += acg.cg_cs.cs_nffree;
538	sblock.fs_cstotal.cs_nbfree += acg.cg_cs.cs_nbfree;
539	sblock.fs_cstotal.cs_nifree += acg.cg_cs.cs_nifree;
540	*cs = acg.cg_cs;
541	wtfs(fsbtodb(&sblock, cgtod(&sblock, cylno)),
542		sblock.fs_bsize, (char *)&acg, fso, Nflag);
543	DBG_DUMP_CG(&sblock,
544	    "new cg",
545	    &acg);
546
547	DBG_LEAVE;
548	return;
549}
550
551/* ******************************************************* frag_adjust ***** */
552/*
553 * Here we add or subtract (sign +1/-1) the available fragments in a given
554 * block to or from the fragment statistics. By subtracting before and adding
555 * after an operation on the free frag map we can easy update the fragment
556 * statistic, which seems to be otherwise a rather complex operation.
557 */
558static void
559frag_adjust(ufs2_daddr_t frag, int sign)
560{
561	DBG_FUNC("frag_adjust")
562	int fragsize;
563	int f;
564
565	DBG_ENTER;
566
567	fragsize=0;
568	/*
569	 * Here frag only needs to point to any fragment in the block we want
570	 * to examine.
571	 */
572	for(f=rounddown(frag, sblock.fs_frag);
573	    f<roundup(frag+1, sblock.fs_frag);
574	    f++) {
575		/*
576		 * Count contiguous free fragments.
577		 */
578		if(isset(cg_blksfree(&acg), f)) {
579			fragsize++;
580		} else {
581			if(fragsize && fragsize<sblock.fs_frag) {
582				/*
583				 * We found something in between.
584				 */
585				acg.cg_frsum[fragsize]+=sign;
586				DBG_PRINT2("frag_adjust [%d]+=%d\n",
587				    fragsize,
588				    sign);
589			}
590			fragsize=0;
591		}
592	}
593	if(fragsize && fragsize<sblock.fs_frag) {
594		/*
595		 * We found something.
596		 */
597		acg.cg_frsum[fragsize]+=sign;
598		DBG_PRINT2("frag_adjust [%d]+=%d\n",
599		    fragsize,
600		    sign);
601	}
602	DBG_PRINT2("frag_adjust [[%d]]+=%d\n",
603	    fragsize,
604	    sign);
605
606	DBG_LEAVE;
607	return;
608}
609
610/* ******************************************************* cond_bl_upd ***** */
611/*
612 * Here we conditionally update a pointer to a fragment. We check for all
613 * relocated blocks if any of its fragments is referenced by the current
614 * field, and update the pointer to the respective fragment in our new
615 * block.  If we find a reference we write back the block immediately,
616 * as there is no easy way for our general block reading engine to figure
617 * out if a write back operation is needed.
618 */
619static int
620cond_bl_upd(ufs2_daddr_t *block, struct gfs_bpp *field, int fsi, int fso,
621    unsigned int Nflag)
622{
623	DBG_FUNC("cond_bl_upd")
624	struct gfs_bpp *f;
625	ufs2_daddr_t src, dst;
626	int fragnum;
627	void *ibuf;
628
629	DBG_ENTER;
630
631	for (f = field; f->old != 0; f++) {
632		src = *block;
633		if (fragstoblks(&sblock, src) != f->old)
634			continue;
635		/*
636		 * The fragment is part of the block, so update.
637		 */
638		dst = blkstofrags(&sblock, f->new);
639		fragnum = fragnum(&sblock, src);
640		*block = dst + fragnum;
641		f->found++;
642		DBG_PRINT3("scg (%jd->%jd)[%d] reference updated\n",
643		    (intmax_t)f->old,
644		    (intmax_t)f->new,
645		    fragnum);
646
647		/*
648		 * Copy the block back immediately.
649		 *
650		 * XXX	If src is is from an indirect block we have
651		 *	to implement copy on write here in case of
652		 *	active snapshots.
653		 */
654		ibuf = malloc(sblock.fs_bsize);
655		if (!ibuf)
656			errx(1, "malloc failed");
657		src -= fragnum;
658		rdfs(fsbtodb(&sblock, src), (size_t)sblock.fs_bsize, ibuf, fsi);
659		wtfs(dst, (size_t)sblock.fs_bsize, ibuf, fso, Nflag);
660		free(ibuf);
661		/*
662		 * The same block can't be found again in this loop.
663		 */
664		return (1);
665	}
666
667	DBG_LEAVE;
668	return (0);
669}
670
671/* ************************************************************ updjcg ***** */
672/*
673 * Here we do all needed work for the former last cylinder group. It has to be
674 * changed in any case, even if the file system ended exactly on the end of
675 * this group, as there is some slightly inconsistent handling of the number
676 * of cylinders in the cylinder group. We start again by reading the cylinder
677 * group from disk. If the last block was not fully available, we first handle
678 * the missing fragments, then we handle all new full blocks in that file
679 * system and finally we handle the new last fragmented block in the file
680 * system.  We again have to handle the fragment statistics rotational layout
681 * tables and cluster summary during all those operations.
682 */
683static void
684updjcg(int cylno, time_t utime, int fsi, int fso, unsigned int Nflag)
685{
686	DBG_FUNC("updjcg")
687	ufs2_daddr_t	cbase, dmax, dupper;
688	struct csum	*cs;
689	int	i,k;
690	int	j=0;
691
692	DBG_ENTER;
693
694	/*
695	 * Read the former last (joining) cylinder group from disk, and make
696	 * a copy.
697	 */
698	rdfs(fsbtodb(&osblock, cgtod(&osblock, cylno)),
699	    (size_t)osblock.fs_cgsize, (void *)&aocg, fsi);
700	DBG_PRINT0("jcg read\n");
701	DBG_DUMP_CG(&sblock,
702	    "old joining cg",
703	    &aocg);
704
705	memcpy((void *)&cgun1, (void *)&cgun2, sizeof(cgun2));
706
707	/*
708	 * If the cylinder group had already its new final size almost
709	 * nothing is to be done ... except:
710	 * For some reason the value of cg_ncyl in the last cylinder group has
711	 * to be zero instead of fs_cpg. As this is now no longer the last
712	 * cylinder group we have to change that value now to fs_cpg.
713	 */
714
715	if(cgbase(&osblock, cylno+1) == osblock.fs_size) {
716		if (sblock.fs_magic == FS_UFS1_MAGIC)
717			acg.cg_old_ncyl=sblock.fs_old_cpg;
718
719		wtfs(fsbtodb(&sblock, cgtod(&sblock, cylno)),
720		    (size_t)sblock.fs_cgsize, (void *)&acg, fso, Nflag);
721		DBG_PRINT0("jcg written\n");
722		DBG_DUMP_CG(&sblock,
723		    "new joining cg",
724		    &acg);
725
726		DBG_LEAVE;
727		return;
728	}
729
730	/*
731	 * Set up some variables needed later.
732	 */
733	cbase = cgbase(&sblock, cylno);
734	dmax = cbase + sblock.fs_fpg;
735	if (dmax > sblock.fs_size)
736		dmax = sblock.fs_size;
737	dupper = cgdmin(&sblock, cylno) - cbase;
738	if (cylno == 0) { /* XXX fscs may be relocated */
739		dupper += howmany(sblock.fs_cssize, sblock.fs_fsize);
740	}
741
742	/*
743	 * Set pointer to the cylinder summary for our cylinder group.
744	 */
745	cs = fscs + cylno;
746
747	/*
748	 * Touch the cylinder group, update all fields in the cylinder group as
749	 * needed, update the free space in the superblock.
750	 */
751	acg.cg_time = utime;
752	if ((unsigned)cylno == sblock.fs_ncg - 1) {
753		/*
754		 * This is still the last cylinder group.
755		 */
756		if (sblock.fs_magic == FS_UFS1_MAGIC)
757			acg.cg_old_ncyl =
758			    sblock.fs_old_ncyl % sblock.fs_old_cpg;
759	} else {
760		acg.cg_old_ncyl = sblock.fs_old_cpg;
761	}
762	DBG_PRINT2("jcg dbg: %d %u",
763	    cylno,
764	    sblock.fs_ncg);
765#ifdef FS_DEBUG
766	if (sblock.fs_magic == FS_UFS1_MAGIC)
767		DBG_PRINT2("%d %u",
768		    acg.cg_old_ncyl,
769		    sblock.fs_old_cpg);
770#endif
771	DBG_PRINT0("\n");
772	acg.cg_ndblk = dmax - cbase;
773	sblock.fs_dsize += acg.cg_ndblk-aocg.cg_ndblk;
774	if (sblock.fs_contigsumsize > 0) {
775		acg.cg_nclusterblks = acg.cg_ndblk / sblock.fs_frag;
776	}
777
778	/*
779	 * Now we have to update the free fragment bitmap for our new free
780	 * space.  There again we have to handle the fragmentation and also
781	 * the rotational layout tables and the cluster summary.  This is
782	 * also done per fragment for the first new block if the old file
783	 * system end was not on a block boundary, per fragment for the new
784	 * last block if the new file system end is not on a block boundary,
785	 * and per block for all space in between.
786	 *
787	 * Handle the first new block here if it was partially available
788	 * before.
789	 */
790	if(osblock.fs_size % sblock.fs_frag) {
791		if(roundup(osblock.fs_size, sblock.fs_frag)<=sblock.fs_size) {
792			/*
793			 * The new space is enough to fill at least this
794			 * block
795			 */
796			j=0;
797			for(i=roundup(osblock.fs_size-cbase, sblock.fs_frag)-1;
798			    i>=osblock.fs_size-cbase;
799			    i--) {
800				setbit(cg_blksfree(&acg), i);
801				acg.cg_cs.cs_nffree++;
802				j++;
803			}
804
805			/*
806			 * Check if the fragment just created could join an
807			 * already existing fragment at the former end of the
808			 * file system.
809			 */
810			if(isblock(&sblock, cg_blksfree(&acg),
811			    ((osblock.fs_size - cgbase(&sblock, cylno))/
812			    sblock.fs_frag))) {
813				/*
814				 * The block is now completely available.
815				 */
816				DBG_PRINT0("block was\n");
817				acg.cg_frsum[osblock.fs_size%sblock.fs_frag]--;
818				acg.cg_cs.cs_nbfree++;
819				acg.cg_cs.cs_nffree-=sblock.fs_frag;
820				k=rounddown(osblock.fs_size-cbase,
821				    sblock.fs_frag);
822				updclst((osblock.fs_size-cbase)/sblock.fs_frag);
823			} else {
824				/*
825				 * Lets rejoin a possible partially growed
826				 * fragment.
827				 */
828				k=0;
829				while(isset(cg_blksfree(&acg), i) &&
830				    (i>=rounddown(osblock.fs_size-cbase,
831				    sblock.fs_frag))) {
832					i--;
833					k++;
834				}
835				if(k) {
836					acg.cg_frsum[k]--;
837				}
838				acg.cg_frsum[k+j]++;
839			}
840		} else {
841			/*
842			 * We only grow by some fragments within this last
843			 * block.
844			 */
845			for(i=sblock.fs_size-cbase-1;
846				i>=osblock.fs_size-cbase;
847				i--) {
848				setbit(cg_blksfree(&acg), i);
849				acg.cg_cs.cs_nffree++;
850				j++;
851			}
852			/*
853			 * Lets rejoin a possible partially growed fragment.
854			 */
855			k=0;
856			while(isset(cg_blksfree(&acg), i) &&
857			    (i>=rounddown(osblock.fs_size-cbase,
858			    sblock.fs_frag))) {
859				i--;
860				k++;
861			}
862			if(k) {
863				acg.cg_frsum[k]--;
864			}
865			acg.cg_frsum[k+j]++;
866		}
867	}
868
869	/*
870	 * Handle all new complete blocks here.
871	 */
872	for(i=roundup(osblock.fs_size-cbase, sblock.fs_frag);
873	    i+sblock.fs_frag<=dmax-cbase;	/* XXX <= or only < ? */
874	    i+=sblock.fs_frag) {
875		j = i / sblock.fs_frag;
876		setblock(&sblock, cg_blksfree(&acg), j);
877		updclst(j);
878		acg.cg_cs.cs_nbfree++;
879	}
880
881	/*
882	 * Handle the last new block if there are stll some new fragments left.
883	 * Here we don't have to bother about the cluster summary or the even
884	 * the rotational layout table.
885	 */
886	if (i < (dmax - cbase)) {
887		acg.cg_frsum[dmax - cbase - i]++;
888		for (; i < dmax - cbase; i++) {
889			setbit(cg_blksfree(&acg), i);
890			acg.cg_cs.cs_nffree++;
891		}
892	}
893
894	sblock.fs_cstotal.cs_nffree +=
895	    (acg.cg_cs.cs_nffree - aocg.cg_cs.cs_nffree);
896	sblock.fs_cstotal.cs_nbfree +=
897	    (acg.cg_cs.cs_nbfree - aocg.cg_cs.cs_nbfree);
898	/*
899	 * The following statistics are not changed here:
900	 *     sblock.fs_cstotal.cs_ndir
901	 *     sblock.fs_cstotal.cs_nifree
902	 * As the statistics for this cylinder group are ready, copy it to
903	 * the summary information array.
904	 */
905	*cs = acg.cg_cs;
906
907	/*
908	 * Write the updated "joining" cylinder group back to disk.
909	 */
910	wtfs(fsbtodb(&sblock, cgtod(&sblock, cylno)), (size_t)sblock.fs_cgsize,
911	    (void *)&acg, fso, Nflag);
912	DBG_PRINT0("jcg written\n");
913	DBG_DUMP_CG(&sblock,
914	    "new joining cg",
915	    &acg);
916
917	DBG_LEAVE;
918	return;
919}
920
921/* ********************************************************** updcsloc ***** */
922/*
923 * Here we update the location of the cylinder summary. We have two possible
924 * ways of growing the cylinder summary.
925 * (1)	We can try to grow the summary in the current location, and relocate
926 *	possibly used blocks within the current cylinder group.
927 * (2)	Alternatively we can relocate the whole cylinder summary to the first
928 *	new completely empty cylinder group. Once the cylinder summary is no
929 *	longer in the beginning of the first cylinder group you should never
930 *	use a version of fsck which is not aware of the possibility to have
931 *	this structure in a non standard place.
932 * Option (1) is considered to be less intrusive to the structure of the file-
933 * system. So we try to stick to that whenever possible. If there is not enough
934 * space in the cylinder group containing the cylinder summary we have to use
935 * method (2). In case of active snapshots in the file system we probably can
936 * completely avoid implementing copy on write if we stick to method (2) only.
937 */
938static void
939updcsloc(time_t utime, int fsi, int fso, unsigned int Nflag)
940{
941	DBG_FUNC("updcsloc")
942	struct csum	*cs;
943	int	ocscg, ncscg;
944	int	blocks;
945	ufs2_daddr_t	cbase, dupper, odupper, d, f, g;
946	int	ind, inc;
947	uint	cylno;
948	struct gfs_bpp	*bp;
949	int	i, l;
950	int	lcs=0;
951	int	block;
952
953	DBG_ENTER;
954
955	if(howmany(sblock.fs_cssize, sblock.fs_fsize) ==
956	    howmany(osblock.fs_cssize, osblock.fs_fsize)) {
957		/*
958		 * No new fragment needed.
959		 */
960		DBG_LEAVE;
961		return;
962	}
963	ocscg=dtog(&osblock, osblock.fs_csaddr);
964	cs=fscs+ocscg;
965	blocks = 1+howmany(sblock.fs_cssize, sblock.fs_bsize)-
966	    howmany(osblock.fs_cssize, osblock.fs_bsize);
967
968	/*
969	 * Read original cylinder group from disk, and make a copy.
970	 * XXX	If Nflag is set in some very rare cases we now miss
971	 *	some changes done in updjcg by reading the unmodified
972	 *	block from disk.
973	 */
974	rdfs(fsbtodb(&osblock, cgtod(&osblock, ocscg)),
975	    (size_t)osblock.fs_cgsize, (void *)&aocg, fsi);
976	DBG_PRINT0("oscg read\n");
977	DBG_DUMP_CG(&sblock,
978	    "old summary cg",
979	    &aocg);
980
981	memcpy((void *)&cgun1, (void *)&cgun2, sizeof(cgun2));
982
983	/*
984	 * Touch the cylinder group, set up local variables needed later
985	 * and update the superblock.
986	 */
987	acg.cg_time = utime;
988
989	/*
990	 * XXX	In the case of having active snapshots we may need much more
991	 *	blocks for the copy on write. We need each block twice, and
992	 *	also up to 8*3 blocks for indirect blocks for all possible
993	 *	references.
994	 */
995	if(/*((int)sblock.fs_time&0x3)>0||*/ cs->cs_nbfree < blocks) {
996		/*
997		 * There is not enough space in the old cylinder group to
998		 * relocate all blocks as needed, so we relocate the whole
999		 * cylinder group summary to a new group. We try to use the
1000		 * first complete new cylinder group just created. Within the
1001		 * cylinder group we align the area immediately after the
1002		 * cylinder group information location in order to be as
1003		 * close as possible to the original implementation of ffs.
1004		 *
1005		 * First we have to make sure we'll find enough space in the
1006		 * new cylinder group. If not, then we currently give up.
1007		 * We start with freeing everything which was used by the
1008		 * fragments of the old cylinder summary in the current group.
1009		 * Now we write back the group meta data, read in the needed
1010		 * meta data from the new cylinder group, and start allocating
1011		 * within that group. Here we can assume, the group to be
1012		 * completely empty. Which makes the handling of fragments and
1013		 * clusters a lot easier.
1014		 */
1015		DBG_TRC;
1016		if(sblock.fs_ncg-osblock.fs_ncg < 2) {
1017			errx(2, "panic: not enough space");
1018		}
1019
1020		/*
1021		 * Point "d" to the first fragment not used by the cylinder
1022		 * summary.
1023		 */
1024		d=osblock.fs_csaddr+(osblock.fs_cssize/osblock.fs_fsize);
1025
1026		/*
1027		 * Set up last cluster size ("lcs") already here. Calculate
1028		 * the size for the trailing cluster just behind where "d"
1029		 * points to.
1030		 */
1031		if(sblock.fs_contigsumsize > 0) {
1032			for(block=howmany(d%sblock.fs_fpg, sblock.fs_frag),
1033			    lcs=0; lcs<sblock.fs_contigsumsize;
1034			    block++, lcs++) {
1035				if(isclr(cg_clustersfree(&acg), block)){
1036					break;
1037				}
1038			}
1039		}
1040
1041		/*
1042		 * Point "d" to the last frag used by the cylinder summary.
1043		 */
1044		d--;
1045
1046		DBG_PRINT1("d=%jd\n",
1047		    (intmax_t)d);
1048		if((d+1)%sblock.fs_frag) {
1049			/*
1050			 * The end of the cylinder summary is not a complete
1051			 * block.
1052			 */
1053			DBG_TRC;
1054			frag_adjust(d%sblock.fs_fpg, -1);
1055			for(; (d+1)%sblock.fs_frag; d--) {
1056				DBG_PRINT1("d=%jd\n",
1057				    (intmax_t)d);
1058				setbit(cg_blksfree(&acg), d%sblock.fs_fpg);
1059				acg.cg_cs.cs_nffree++;
1060				sblock.fs_cstotal.cs_nffree++;
1061			}
1062			/*
1063			 * Point "d" to the last fragment of the last
1064			 * (incomplete) block of the cylinder summary.
1065			 */
1066			d++;
1067			frag_adjust(d%sblock.fs_fpg, 1);
1068
1069			if(isblock(&sblock, cg_blksfree(&acg),
1070			    (d%sblock.fs_fpg)/sblock.fs_frag)) {
1071				DBG_PRINT1("d=%jd\n", (intmax_t)d);
1072				acg.cg_cs.cs_nffree-=sblock.fs_frag;
1073				acg.cg_cs.cs_nbfree++;
1074				sblock.fs_cstotal.cs_nffree-=sblock.fs_frag;
1075				sblock.fs_cstotal.cs_nbfree++;
1076				if(sblock.fs_contigsumsize > 0) {
1077					setbit(cg_clustersfree(&acg),
1078					    (d%sblock.fs_fpg)/sblock.fs_frag);
1079					if(lcs < sblock.fs_contigsumsize) {
1080						if(lcs) {
1081							cg_clustersum(&acg)
1082							    [lcs]--;
1083						}
1084						lcs++;
1085						cg_clustersum(&acg)[lcs]++;
1086					}
1087				}
1088			}
1089			/*
1090			 * Point "d" to the first fragment of the block before
1091			 * the last incomplete block.
1092			 */
1093			d--;
1094		}
1095
1096		DBG_PRINT1("d=%jd\n", (intmax_t)d);
1097		for(d=rounddown(d, sblock.fs_frag); d >= osblock.fs_csaddr;
1098		    d-=sblock.fs_frag) {
1099			DBG_TRC;
1100			DBG_PRINT1("d=%jd\n", (intmax_t)d);
1101			setblock(&sblock, cg_blksfree(&acg),
1102			    (d%sblock.fs_fpg)/sblock.fs_frag);
1103			acg.cg_cs.cs_nbfree++;
1104			sblock.fs_cstotal.cs_nbfree++;
1105			if(sblock.fs_contigsumsize > 0) {
1106				setbit(cg_clustersfree(&acg),
1107				    (d%sblock.fs_fpg)/sblock.fs_frag);
1108				/*
1109				 * The last cluster size is already set up.
1110				 */
1111				if(lcs < sblock.fs_contigsumsize) {
1112					if(lcs) {
1113						cg_clustersum(&acg)[lcs]--;
1114					}
1115					lcs++;
1116					cg_clustersum(&acg)[lcs]++;
1117				}
1118			}
1119		}
1120		*cs = acg.cg_cs;
1121
1122		/*
1123		 * Now write the former cylinder group containing the cylinder
1124		 * summary back to disk.
1125		 */
1126		wtfs(fsbtodb(&sblock, cgtod(&sblock, ocscg)),
1127		    (size_t)sblock.fs_cgsize, (void *)&acg, fso, Nflag);
1128		DBG_PRINT0("oscg written\n");
1129		DBG_DUMP_CG(&sblock,
1130		    "old summary cg",
1131		    &acg);
1132
1133		/*
1134		 * Find the beginning of the new cylinder group containing the
1135		 * cylinder summary.
1136		 */
1137		sblock.fs_csaddr=cgdmin(&sblock, osblock.fs_ncg);
1138		ncscg=dtog(&sblock, sblock.fs_csaddr);
1139		cs=fscs+ncscg;
1140
1141
1142		/*
1143		 * If Nflag is specified, we would now read random data instead
1144		 * of an empty cg structure from disk. So we can't simulate that
1145		 * part for now.
1146		 */
1147		if(Nflag) {
1148			DBG_PRINT0("nscg update skipped\n");
1149			DBG_LEAVE;
1150			return;
1151		}
1152
1153		/*
1154		 * Read the future cylinder group containing the cylinder
1155		 * summary from disk, and make a copy.
1156		 */
1157		rdfs(fsbtodb(&sblock, cgtod(&sblock, ncscg)),
1158		    (size_t)sblock.fs_cgsize, (void *)&aocg, fsi);
1159		DBG_PRINT0("nscg read\n");
1160		DBG_DUMP_CG(&sblock,
1161		    "new summary cg",
1162		    &aocg);
1163
1164		memcpy((void *)&cgun1, (void *)&cgun2, sizeof(cgun2));
1165
1166		/*
1167		 * Allocate all complete blocks used by the new cylinder
1168		 * summary.
1169		 */
1170		for(d=sblock.fs_csaddr; d+sblock.fs_frag <=
1171		    sblock.fs_csaddr+(sblock.fs_cssize/sblock.fs_fsize);
1172		    d+=sblock.fs_frag) {
1173			clrblock(&sblock, cg_blksfree(&acg),
1174			    (d%sblock.fs_fpg)/sblock.fs_frag);
1175			acg.cg_cs.cs_nbfree--;
1176			sblock.fs_cstotal.cs_nbfree--;
1177			if(sblock.fs_contigsumsize > 0) {
1178				clrbit(cg_clustersfree(&acg),
1179				    (d%sblock.fs_fpg)/sblock.fs_frag);
1180			}
1181		}
1182
1183		/*
1184		 * Allocate all fragments used by the cylinder summary in the
1185		 * last block.
1186		 */
1187		if(d<sblock.fs_csaddr+(sblock.fs_cssize/sblock.fs_fsize)) {
1188			for(; d-sblock.fs_csaddr<
1189			    sblock.fs_cssize/sblock.fs_fsize;
1190			    d++) {
1191				clrbit(cg_blksfree(&acg), d%sblock.fs_fpg);
1192				acg.cg_cs.cs_nffree--;
1193				sblock.fs_cstotal.cs_nffree--;
1194			}
1195			acg.cg_cs.cs_nbfree--;
1196			acg.cg_cs.cs_nffree+=sblock.fs_frag;
1197			sblock.fs_cstotal.cs_nbfree--;
1198			sblock.fs_cstotal.cs_nffree+=sblock.fs_frag;
1199			if(sblock.fs_contigsumsize > 0) {
1200				clrbit(cg_clustersfree(&acg),
1201				    (d%sblock.fs_fpg)/sblock.fs_frag);
1202			}
1203
1204			frag_adjust(d%sblock.fs_fpg, +1);
1205		}
1206		/*
1207		 * XXX	Handle the cluster statistics here in the case this
1208		 *	cylinder group is now almost full, and the remaining
1209		 *	space is less then the maximum cluster size. This is
1210		 *	probably not needed, as you would hardly find a file
1211		 *	system which has only MAXCSBUFS+FS_MAXCONTIG of free
1212		 *	space right behind the cylinder group information in
1213		 *	any new cylinder group.
1214		 */
1215
1216		/*
1217		 * Update our statistics in the cylinder summary.
1218		 */
1219		*cs = acg.cg_cs;
1220
1221		/*
1222		 * Write the new cylinder group containing the cylinder summary
1223		 * back to disk.
1224		 */
1225		wtfs(fsbtodb(&sblock, cgtod(&sblock, ncscg)),
1226		    (size_t)sblock.fs_cgsize, (void *)&acg, fso, Nflag);
1227		DBG_PRINT0("nscg written\n");
1228		DBG_DUMP_CG(&sblock,
1229		    "new summary cg",
1230		    &acg);
1231
1232		DBG_LEAVE;
1233		return;
1234	}
1235	/*
1236	 * We have got enough of space in the current cylinder group, so we
1237	 * can relocate just a few blocks, and let the summary information
1238	 * grow in place where it is right now.
1239	 */
1240	DBG_TRC;
1241
1242	cbase = cgbase(&osblock, ocscg);	/* old and new are equal */
1243	dupper = sblock.fs_csaddr - cbase +
1244	    howmany(sblock.fs_cssize, sblock.fs_fsize);
1245	odupper = osblock.fs_csaddr - cbase +
1246	    howmany(osblock.fs_cssize, osblock.fs_fsize);
1247
1248	sblock.fs_dsize -= dupper-odupper;
1249
1250	/*
1251	 * Allocate the space for the array of blocks to be relocated.
1252	 */
1253 	bp=(struct gfs_bpp *)malloc(((dupper-odupper)/sblock.fs_frag+2)*
1254	    sizeof(struct gfs_bpp));
1255	if(bp == NULL) {
1256		errx(1, "malloc failed");
1257	}
1258	memset((char *)bp, 0, ((dupper-odupper)/sblock.fs_frag+2)*
1259	    sizeof(struct gfs_bpp));
1260
1261	/*
1262	 * Lock all new frags needed for the cylinder group summary. This is
1263	 * done per fragment in the first and last block of the new required
1264	 * area, and per block for all other blocks.
1265	 *
1266	 * Handle the first new block here (but only if some fragments where
1267	 * already used for the cylinder summary).
1268	 */
1269	ind=0;
1270	frag_adjust(odupper, -1);
1271	for(d=odupper; ((d<dupper)&&(d%sblock.fs_frag)); d++) {
1272		DBG_PRINT1("scg first frag check loop d=%jd\n",
1273		    (intmax_t)d);
1274		if(isclr(cg_blksfree(&acg), d)) {
1275			if (!ind) {
1276				bp[ind].old=d/sblock.fs_frag;
1277				bp[ind].flags|=GFS_FL_FIRST;
1278				if(roundup(d, sblock.fs_frag) >= dupper) {
1279					bp[ind].flags|=GFS_FL_LAST;
1280				}
1281				ind++;
1282			}
1283		} else {
1284			clrbit(cg_blksfree(&acg), d);
1285			acg.cg_cs.cs_nffree--;
1286			sblock.fs_cstotal.cs_nffree--;
1287		}
1288		/*
1289		 * No cluster handling is needed here, as there was at least
1290		 * one fragment in use by the cylinder summary in the old
1291		 * file system.
1292		 * No block-free counter handling here as this block was not
1293		 * a free block.
1294		 */
1295	}
1296	frag_adjust(odupper, 1);
1297
1298	/*
1299	 * Handle all needed complete blocks here.
1300	 */
1301	for(; d+sblock.fs_frag<=dupper; d+=sblock.fs_frag) {
1302		DBG_PRINT1("scg block check loop d=%jd\n",
1303		    (intmax_t)d);
1304		if(!isblock(&sblock, cg_blksfree(&acg), d/sblock.fs_frag)) {
1305			for(f=d; f<d+sblock.fs_frag; f++) {
1306				if(isset(cg_blksfree(&aocg), f)) {
1307					acg.cg_cs.cs_nffree--;
1308					sblock.fs_cstotal.cs_nffree--;
1309				}
1310			}
1311			clrblock(&sblock, cg_blksfree(&acg), d/sblock.fs_frag);
1312			bp[ind].old=d/sblock.fs_frag;
1313			ind++;
1314		} else {
1315			clrblock(&sblock, cg_blksfree(&acg), d/sblock.fs_frag);
1316			acg.cg_cs.cs_nbfree--;
1317			sblock.fs_cstotal.cs_nbfree--;
1318			if(sblock.fs_contigsumsize > 0) {
1319				clrbit(cg_clustersfree(&acg), d/sblock.fs_frag);
1320				for(lcs=0, l=(d/sblock.fs_frag)+1;
1321				    lcs<sblock.fs_contigsumsize;
1322				    l++, lcs++ ) {
1323					if(isclr(cg_clustersfree(&acg),l)){
1324						break;
1325					}
1326				}
1327				if(lcs < sblock.fs_contigsumsize) {
1328					cg_clustersum(&acg)[lcs+1]--;
1329					if(lcs) {
1330						cg_clustersum(&acg)[lcs]++;
1331					}
1332				}
1333			}
1334		}
1335		/*
1336		 * No fragment counter handling is needed here, as this finally
1337		 * doesn't change after the relocation.
1338		 */
1339	}
1340
1341	/*
1342	 * Handle all fragments needed in the last new affected block.
1343	 */
1344	if(d<dupper) {
1345		frag_adjust(dupper-1, -1);
1346
1347		if(isblock(&sblock, cg_blksfree(&acg), d/sblock.fs_frag)) {
1348			acg.cg_cs.cs_nbfree--;
1349			sblock.fs_cstotal.cs_nbfree--;
1350			acg.cg_cs.cs_nffree+=sblock.fs_frag;
1351			sblock.fs_cstotal.cs_nffree+=sblock.fs_frag;
1352			if(sblock.fs_contigsumsize > 0) {
1353				clrbit(cg_clustersfree(&acg), d/sblock.fs_frag);
1354				for(lcs=0, l=(d/sblock.fs_frag)+1;
1355				    lcs<sblock.fs_contigsumsize;
1356				    l++, lcs++ ) {
1357					if(isclr(cg_clustersfree(&acg),l)){
1358						break;
1359					}
1360				}
1361				if(lcs < sblock.fs_contigsumsize) {
1362					cg_clustersum(&acg)[lcs+1]--;
1363					if(lcs) {
1364						cg_clustersum(&acg)[lcs]++;
1365					}
1366				}
1367			}
1368		}
1369
1370		for(; d<dupper; d++) {
1371			DBG_PRINT1("scg second frag check loop d=%jd\n",
1372			    (intmax_t)d);
1373			if(isclr(cg_blksfree(&acg), d)) {
1374				bp[ind].old=d/sblock.fs_frag;
1375				bp[ind].flags|=GFS_FL_LAST;
1376			} else {
1377				clrbit(cg_blksfree(&acg), d);
1378				acg.cg_cs.cs_nffree--;
1379				sblock.fs_cstotal.cs_nffree--;
1380			}
1381		}
1382		if(bp[ind].flags & GFS_FL_LAST) { /* we have to advance here */
1383			ind++;
1384		}
1385		frag_adjust(dupper-1, 1);
1386	}
1387
1388	/*
1389	 * If we found a block to relocate just do so.
1390	 */
1391	if(ind) {
1392		for(i=0; i<ind; i++) {
1393			if(!bp[i].old) { /* no more blocks listed */
1394				/*
1395				 * XXX	A relative blocknumber should not be
1396				 *	zero, which is not explicitly
1397				 *	guaranteed by our code.
1398				 */
1399				break;
1400			}
1401			/*
1402			 * Allocate a complete block in the same (current)
1403			 * cylinder group.
1404			 */
1405			bp[i].new=alloc()/sblock.fs_frag;
1406
1407			/*
1408			 * There is no frag_adjust() needed for the new block
1409			 * as it will have no fragments yet :-).
1410			 */
1411			for(f=bp[i].old*sblock.fs_frag,
1412			    g=bp[i].new*sblock.fs_frag;
1413			    f<(bp[i].old+1)*sblock.fs_frag;
1414			    f++, g++) {
1415				if(isset(cg_blksfree(&aocg), f)) {
1416					setbit(cg_blksfree(&acg), g);
1417					acg.cg_cs.cs_nffree++;
1418					sblock.fs_cstotal.cs_nffree++;
1419				}
1420			}
1421
1422			/*
1423			 * Special handling is required if this was the first
1424			 * block. We have to consider the fragments which were
1425			 * used by the cylinder summary in the original block
1426			 * which re to be free in the copy of our block.  We
1427			 * have to be careful if this first block happens to
1428			 * be also the last block to be relocated.
1429			 */
1430			if(bp[i].flags & GFS_FL_FIRST) {
1431				for(f=bp[i].old*sblock.fs_frag,
1432				    g=bp[i].new*sblock.fs_frag;
1433				    f<odupper;
1434				    f++, g++) {
1435					setbit(cg_blksfree(&acg), g);
1436					acg.cg_cs.cs_nffree++;
1437					sblock.fs_cstotal.cs_nffree++;
1438				}
1439				if(!(bp[i].flags & GFS_FL_LAST)) {
1440					frag_adjust(bp[i].new*sblock.fs_frag,1);
1441				}
1442			}
1443
1444			/*
1445			 * Special handling is required if this is the last
1446			 * block to be relocated.
1447			 */
1448			if(bp[i].flags & GFS_FL_LAST) {
1449				frag_adjust(bp[i].new*sblock.fs_frag, 1);
1450				frag_adjust(bp[i].old*sblock.fs_frag, -1);
1451				for(f=dupper;
1452				    f<roundup(dupper, sblock.fs_frag);
1453				    f++) {
1454					if(isclr(cg_blksfree(&acg), f)) {
1455						setbit(cg_blksfree(&acg), f);
1456						acg.cg_cs.cs_nffree++;
1457						sblock.fs_cstotal.cs_nffree++;
1458					}
1459				}
1460				frag_adjust(bp[i].old*sblock.fs_frag, 1);
1461			}
1462
1463			/*
1464			 * !!! Attach the cylindergroup offset here.
1465			 */
1466			bp[i].old+=cbase/sblock.fs_frag;
1467			bp[i].new+=cbase/sblock.fs_frag;
1468
1469			/*
1470			 * Copy the content of the block.
1471			 */
1472			/*
1473			 * XXX	Here we will have to implement a copy on write
1474			 *	in the case we have any active snapshots.
1475			 */
1476			rdfs(fsbtodb(&sblock, bp[i].old*sblock.fs_frag),
1477			    (size_t)sblock.fs_bsize, (void *)&ablk, fsi);
1478			wtfs(fsbtodb(&sblock, bp[i].new*sblock.fs_frag),
1479			    (size_t)sblock.fs_bsize, (void *)&ablk, fso, Nflag);
1480			DBG_DUMP_HEX(&sblock,
1481			    "copied full block",
1482			    (unsigned char *)&ablk);
1483
1484			DBG_PRINT2("scg (%jd->%jd) block relocated\n",
1485			    (intmax_t)bp[i].old,
1486			    (intmax_t)bp[i].new);
1487		}
1488
1489		/*
1490		 * Now we have to update all references to any fragment which
1491		 * belongs to any block relocated. We iterate now over all
1492		 * cylinder groups, within those over all non zero length
1493		 * inodes.
1494		 */
1495		for(cylno=0; cylno<osblock.fs_ncg; cylno++) {
1496			DBG_PRINT1("scg doing cg (%d)\n",
1497			    cylno);
1498			for(inc=osblock.fs_ipg-1 ; inc>0 ; inc--) {
1499				updrefs(cylno, (ino_t)inc, bp, fsi, fso, Nflag);
1500			}
1501		}
1502
1503		/*
1504		 * All inodes are checked, now make sure the number of
1505		 * references found make sense.
1506		 */
1507		for(i=0; i<ind; i++) {
1508			if(!bp[i].found || (bp[i].found>sblock.fs_frag)) {
1509				warnx("error: %jd refs found for block %jd.",
1510				    (intmax_t)bp[i].found, (intmax_t)bp[i].old);
1511			}
1512
1513		}
1514	}
1515	/*
1516	 * The following statistics are not changed here:
1517	 *     sblock.fs_cstotal.cs_ndir
1518	 *     sblock.fs_cstotal.cs_nifree
1519	 * The following statistics were already updated on the fly:
1520	 *     sblock.fs_cstotal.cs_nffree
1521	 *     sblock.fs_cstotal.cs_nbfree
1522	 * As the statistics for this cylinder group are ready, copy it to
1523	 * the summary information array.
1524	 */
1525
1526	*cs = acg.cg_cs;
1527
1528	/*
1529	 * Write summary cylinder group back to disk.
1530	 */
1531	wtfs(fsbtodb(&sblock, cgtod(&sblock, ocscg)), (size_t)sblock.fs_cgsize,
1532	    (void *)&acg, fso, Nflag);
1533	DBG_PRINT0("scg written\n");
1534	DBG_DUMP_CG(&sblock,
1535	    "new summary cg",
1536	    &acg);
1537
1538	DBG_LEAVE;
1539	return;
1540}
1541
1542/* ************************************************************** rdfs ***** */
1543/*
1544 * Here we read some block(s) from disk.
1545 */
1546static void
1547rdfs(ufs2_daddr_t bno, size_t size, void *bf, int fsi)
1548{
1549	DBG_FUNC("rdfs")
1550	ssize_t	n;
1551
1552	DBG_ENTER;
1553
1554	if (bno < 0) {
1555		err(32, "rdfs: attempting to read negative block number");
1556	}
1557	if (lseek(fsi, (off_t)bno * DEV_BSIZE, 0) < 0) {
1558		err(33, "rdfs: seek error: %jd", (intmax_t)bno);
1559	}
1560	n = read(fsi, bf, size);
1561	if (n != (ssize_t)size) {
1562		err(34, "rdfs: read error: %jd", (intmax_t)bno);
1563	}
1564
1565	DBG_LEAVE;
1566	return;
1567}
1568
1569/* ************************************************************** wtfs ***** */
1570/*
1571 * Here we write some block(s) to disk.
1572 */
1573static void
1574wtfs(ufs2_daddr_t bno, size_t size, void *bf, int fso, unsigned int Nflag)
1575{
1576	DBG_FUNC("wtfs")
1577	ssize_t	n;
1578
1579	DBG_ENTER;
1580
1581	if (Nflag) {
1582		DBG_LEAVE;
1583		return;
1584	}
1585	if (lseek(fso, (off_t)bno * DEV_BSIZE, SEEK_SET) < 0) {
1586		err(35, "wtfs: seek error: %ld", (long)bno);
1587	}
1588	n = write(fso, bf, size);
1589	if (n != (ssize_t)size) {
1590		err(36, "wtfs: write error: %ld", (long)bno);
1591	}
1592
1593	DBG_LEAVE;
1594	return;
1595}
1596
1597/* ************************************************************* alloc ***** */
1598/*
1599 * Here we allocate a free block in the current cylinder group. It is assumed,
1600 * that acg contains the current cylinder group. As we may take a block from
1601 * somewhere in the file system we have to handle cluster summary here.
1602 */
1603static ufs2_daddr_t
1604alloc(void)
1605{
1606	DBG_FUNC("alloc")
1607	ufs2_daddr_t	d, blkno;
1608	int	lcs1, lcs2;
1609	int	l;
1610	int	csmin, csmax;
1611	int	dlower, dupper, dmax;
1612
1613	DBG_ENTER;
1614
1615	if (acg.cg_magic != CG_MAGIC) {
1616		warnx("acg: bad magic number");
1617		DBG_LEAVE;
1618		return (0);
1619	}
1620	if (acg.cg_cs.cs_nbfree == 0) {
1621		warnx("error: cylinder group ran out of space");
1622		DBG_LEAVE;
1623		return (0);
1624	}
1625	/*
1626	 * We start seeking for free blocks only from the space available after
1627	 * the end of the new grown cylinder summary. Otherwise we allocate a
1628	 * block here which we have to relocate a couple of seconds later again
1629	 * again, and we are not prepared to to this anyway.
1630	 */
1631	blkno=-1;
1632	dlower=cgsblock(&sblock, acg.cg_cgx)-cgbase(&sblock, acg.cg_cgx);
1633	dupper=cgdmin(&sblock, acg.cg_cgx)-cgbase(&sblock, acg.cg_cgx);
1634	dmax=cgbase(&sblock, acg.cg_cgx)+sblock.fs_fpg;
1635	if (dmax > sblock.fs_size) {
1636		dmax = sblock.fs_size;
1637	}
1638	dmax-=cgbase(&sblock, acg.cg_cgx); /* retransform into cg */
1639	csmin=sblock.fs_csaddr-cgbase(&sblock, acg.cg_cgx);
1640	csmax=csmin+howmany(sblock.fs_cssize, sblock.fs_fsize);
1641	DBG_PRINT3("seek range: dl=%d, du=%d, dm=%d\n",
1642	    dlower,
1643	    dupper,
1644	    dmax);
1645	DBG_PRINT2("range cont: csmin=%d, csmax=%d\n",
1646	    csmin,
1647	    csmax);
1648
1649	for(d=0; (d<dlower && blkno==-1); d+=sblock.fs_frag) {
1650		if(d>=csmin && d<=csmax) {
1651			continue;
1652		}
1653		if(isblock(&sblock, cg_blksfree(&acg), fragstoblks(&sblock,
1654		    d))) {
1655			blkno = fragstoblks(&sblock, d);/* Yeah found a block */
1656			break;
1657		}
1658	}
1659	for(d=dupper; (d<dmax && blkno==-1); d+=sblock.fs_frag) {
1660		if(d>=csmin && d<=csmax) {
1661			continue;
1662		}
1663		if(isblock(&sblock, cg_blksfree(&acg), fragstoblks(&sblock,
1664		    d))) {
1665			blkno = fragstoblks(&sblock, d);/* Yeah found a block */
1666			break;
1667		}
1668	}
1669	if(blkno==-1) {
1670		warnx("internal error: couldn't find promised block in cg");
1671		DBG_LEAVE;
1672		return (0);
1673	}
1674
1675	/*
1676	 * This is needed if the block was found already in the first loop.
1677	 */
1678	d=blkstofrags(&sblock, blkno);
1679
1680	clrblock(&sblock, cg_blksfree(&acg), blkno);
1681	if (sblock.fs_contigsumsize > 0) {
1682		/*
1683		 * Handle the cluster allocation bitmap.
1684		 */
1685		clrbit(cg_clustersfree(&acg), blkno);
1686		/*
1687		 * We possibly have split a cluster here, so we have to do
1688		 * recalculate the sizes of the remaining cluster halves now,
1689		 * and use them for updating the cluster summary information.
1690		 *
1691		 * Lets start with the blocks before our allocated block ...
1692		 */
1693		for(lcs1=0, l=blkno-1; lcs1<sblock.fs_contigsumsize;
1694		    l--, lcs1++ ) {
1695			if(isclr(cg_clustersfree(&acg),l)){
1696				break;
1697			}
1698		}
1699		/*
1700		 * ... and continue with the blocks right after our allocated
1701		 * block.
1702		 */
1703		for(lcs2=0, l=blkno+1; lcs2<sblock.fs_contigsumsize;
1704		    l++, lcs2++ ) {
1705			if(isclr(cg_clustersfree(&acg),l)){
1706				break;
1707			}
1708		}
1709
1710		/*
1711		 * Now update all counters.
1712		 */
1713		cg_clustersum(&acg)[MIN(lcs1+lcs2+1,sblock.fs_contigsumsize)]--;
1714		if(lcs1) {
1715			cg_clustersum(&acg)[lcs1]++;
1716		}
1717		if(lcs2) {
1718			cg_clustersum(&acg)[lcs2]++;
1719		}
1720	}
1721	/*
1722	 * Update all statistics based on blocks.
1723	 */
1724	acg.cg_cs.cs_nbfree--;
1725	sblock.fs_cstotal.cs_nbfree--;
1726
1727	DBG_LEAVE;
1728	return (d);
1729}
1730
1731/* *********************************************************** isblock ***** */
1732/*
1733 * Here we check if all frags of a block are free. For more details again
1734 * please see the source of newfs(8), as this function is taken over almost
1735 * unchanged.
1736 */
1737static int
1738isblock(struct fs *fs, unsigned char *cp, int h)
1739{
1740	DBG_FUNC("isblock")
1741	unsigned char	mask;
1742
1743	DBG_ENTER;
1744
1745	switch (fs->fs_frag) {
1746	case 8:
1747		DBG_LEAVE;
1748		return (cp[h] == 0xff);
1749	case 4:
1750		mask = 0x0f << ((h & 0x1) << 2);
1751		DBG_LEAVE;
1752		return ((cp[h >> 1] & mask) == mask);
1753	case 2:
1754		mask = 0x03 << ((h & 0x3) << 1);
1755		DBG_LEAVE;
1756		return ((cp[h >> 2] & mask) == mask);
1757	case 1:
1758		mask = 0x01 << (h & 0x7);
1759		DBG_LEAVE;
1760		return ((cp[h >> 3] & mask) == mask);
1761	default:
1762		fprintf(stderr, "isblock bad fs_frag %d\n", fs->fs_frag);
1763		DBG_LEAVE;
1764		return (0);
1765	}
1766}
1767
1768/* ********************************************************** clrblock ***** */
1769/*
1770 * Here we allocate a complete block in the block map. For more details again
1771 * please see the source of newfs(8), as this function is taken over almost
1772 * unchanged.
1773 */
1774static void
1775clrblock(struct fs *fs, unsigned char *cp, int h)
1776{
1777	DBG_FUNC("clrblock")
1778
1779	DBG_ENTER;
1780
1781	switch ((fs)->fs_frag) {
1782	case 8:
1783		cp[h] = 0;
1784		break;
1785	case 4:
1786		cp[h >> 1] &= ~(0x0f << ((h & 0x1) << 2));
1787		break;
1788	case 2:
1789		cp[h >> 2] &= ~(0x03 << ((h & 0x3) << 1));
1790		break;
1791	case 1:
1792		cp[h >> 3] &= ~(0x01 << (h & 0x7));
1793		break;
1794	default:
1795		warnx("clrblock bad fs_frag %d", fs->fs_frag);
1796		break;
1797	}
1798
1799	DBG_LEAVE;
1800	return;
1801}
1802
1803/* ********************************************************** setblock ***** */
1804/*
1805 * Here we free a complete block in the free block map. For more details again
1806 * please see the source of newfs(8), as this function is taken over almost
1807 * unchanged.
1808 */
1809static void
1810setblock(struct fs *fs, unsigned char *cp, int h)
1811{
1812	DBG_FUNC("setblock")
1813
1814	DBG_ENTER;
1815
1816	switch (fs->fs_frag) {
1817	case 8:
1818		cp[h] = 0xff;
1819		break;
1820	case 4:
1821		cp[h >> 1] |= (0x0f << ((h & 0x1) << 2));
1822		break;
1823	case 2:
1824		cp[h >> 2] |= (0x03 << ((h & 0x3) << 1));
1825		break;
1826	case 1:
1827		cp[h >> 3] |= (0x01 << (h & 0x7));
1828		break;
1829	default:
1830		warnx("setblock bad fs_frag %d", fs->fs_frag);
1831		break;
1832	}
1833
1834	DBG_LEAVE;
1835	return;
1836}
1837
1838/* ************************************************************ ginode ***** */
1839/*
1840 * This function provides access to an individual inode. We find out in which
1841 * block the requested inode is located, read it from disk if needed, and
1842 * return the pointer into that block. We maintain a cache of one block to
1843 * not read the same block again and again if we iterate linearly over all
1844 * inodes.
1845 */
1846static union dinode *
1847ginode(ino_t inumber, int fsi, int cg)
1848{
1849	DBG_FUNC("ginode")
1850	static ino_t	startinum = 0;	/* first inode in cached block */
1851
1852	DBG_ENTER;
1853
1854	/*
1855	 * The inumber passed in is relative to the cg, so use it here to see
1856	 * if the inode has been allocated yet.
1857	 */
1858	if (isclr(cg_inosused(&aocg), inumber)) {
1859		DBG_LEAVE;
1860		return NULL;
1861	}
1862	/*
1863	 * Now make the inumber relative to the entire inode space so it can
1864	 * be sanity checked.
1865	 */
1866	inumber += (cg * sblock.fs_ipg);
1867	if (inumber < ROOTINO) {
1868		DBG_LEAVE;
1869		return NULL;
1870	}
1871	if (inumber > maxino)
1872		errx(8, "bad inode number %d to ginode", inumber);
1873	if (startinum == 0 ||
1874	    inumber < startinum || inumber >= startinum + INOPB(&sblock)) {
1875		inoblk = fsbtodb(&sblock, ino_to_fsba(&sblock, inumber));
1876		rdfs(inoblk, (size_t)sblock.fs_bsize, inobuf, fsi);
1877		startinum = (inumber / INOPB(&sblock)) * INOPB(&sblock);
1878	}
1879	DBG_LEAVE;
1880	if (sblock.fs_magic == FS_UFS1_MAGIC)
1881		return (union dinode *)((uintptr_t)inobuf +
1882		    (inumber % INOPB(&sblock)) * sizeof(struct ufs1_dinode));
1883	return (union dinode *)((uintptr_t)inobuf +
1884	    (inumber % INOPB(&sblock)) * sizeof(struct ufs2_dinode));
1885}
1886
1887/* ****************************************************** charsperline ***** */
1888/*
1889 * Figure out how many lines our current terminal has. For more details again
1890 * please see the source of newfs(8), as this function is taken over almost
1891 * unchanged.
1892 */
1893static int
1894charsperline(void)
1895{
1896	DBG_FUNC("charsperline")
1897	int	columns;
1898	char	*cp;
1899	struct winsize	ws;
1900
1901	DBG_ENTER;
1902
1903	columns = 0;
1904	if (ioctl(0, TIOCGWINSZ, &ws) != -1) {
1905		columns = ws.ws_col;
1906	}
1907	if (columns == 0 && (cp = getenv("COLUMNS"))) {
1908		columns = atoi(cp);
1909	}
1910	if (columns == 0) {
1911		columns = 80;	/* last resort */
1912	}
1913
1914	DBG_LEAVE;
1915	return columns;
1916}
1917
1918/* ****************************************************** get_dev_size ***** */
1919/*
1920 * Get the size of the partition if we can't figure it out from the disklabel,
1921 * e.g. from vinum volumes.
1922 */
1923static void
1924get_dev_size(int fd, int *size)
1925{
1926   int sectorsize;
1927   off_t mediasize;
1928
1929   if (ioctl(fd, DIOCGSECTORSIZE, &sectorsize) == -1)
1930        err(1,"DIOCGSECTORSIZE");
1931   if (ioctl(fd, DIOCGMEDIASIZE, &mediasize) == -1)
1932        err(1,"DIOCGMEDIASIZE");
1933
1934   if (sectorsize <= 0)
1935       errx(1, "bogus sectorsize: %d", sectorsize);
1936
1937   *size = mediasize / sectorsize;
1938}
1939
1940/* ************************************************************** main ***** */
1941/*
1942 * growfs(8)  is a utility which allows to increase the size of an existing
1943 * ufs file system. Currently this can only be done on unmounted file system.
1944 * It recognizes some command line options to specify the new desired size,
1945 * and it does some basic checkings. The old file system size is determined
1946 * and after some more checks like we can really access the new last block
1947 * on the disk etc. we calculate the new parameters for the superblock. After
1948 * having done this we just call growfs() which will do the work.  Before
1949 * we finish the only thing left is to update the disklabel.
1950 * We still have to provide support for snapshots. Therefore we first have to
1951 * understand what data structures are always replicated in the snapshot on
1952 * creation, for all other blocks we touch during our procedure, we have to
1953 * keep the old blocks unchanged somewhere available for the snapshots. If we
1954 * are lucky, then we only have to handle our blocks to be relocated in that
1955 * way.
1956 * Also we have to consider in what order we actually update the critical
1957 * data structures of the file system to make sure, that in case of a disaster
1958 * fsck(8) is still able to restore any lost data.
1959 * The foreseen last step then will be to provide for growing even mounted
1960 * file systems. There we have to extend the mount() system call to provide
1961 * userland access to the file system locking facility.
1962 */
1963int
1964main(int argc, char **argv)
1965{
1966	DBG_FUNC("main")
1967	char	*device, *special, *cp;
1968	int	ch;
1969	unsigned int	size=0;
1970	size_t	len;
1971	unsigned int	Nflag=0;
1972	int	ExpertFlag=0;
1973	struct stat	st;
1974	struct disklabel	*lp;
1975	struct partition	*pp;
1976	int	i,fsi,fso;
1977    u_int32_t p_size;
1978	char	reply[5];
1979#ifdef FSMAXSNAP
1980	int	j;
1981#endif /* FSMAXSNAP */
1982
1983	DBG_ENTER;
1984
1985	while((ch=getopt(argc, argv, "Ns:vy")) != -1) {
1986		switch(ch) {
1987		case 'N':
1988			Nflag=1;
1989			break;
1990		case 's':
1991			size=(size_t)atol(optarg);
1992			if(size<1) {
1993				usage();
1994			}
1995			break;
1996		case 'v': /* for compatibility to newfs */
1997			break;
1998		case 'y':
1999			ExpertFlag=1;
2000			break;
2001		case '?':
2002			/* FALLTHROUGH */
2003		default:
2004			usage();
2005		}
2006	}
2007	argc -= optind;
2008	argv += optind;
2009
2010	if(argc != 1) {
2011		usage();
2012	}
2013	device=*argv;
2014
2015	/*
2016	 * Now try to guess the (raw)device name.
2017	 */
2018	if (0 == strrchr(device, '/')) {
2019		/*
2020		 * No path prefix was given, so try in that order:
2021		 *     /dev/r%s
2022		 *     /dev/%s
2023		 *     /dev/vinum/r%s
2024		 *     /dev/vinum/%s.
2025		 *
2026		 * FreeBSD now doesn't distinguish between raw and block
2027		 * devices any longer, but it should still work this way.
2028		 */
2029		len=strlen(device)+strlen(_PATH_DEV)+2+strlen("vinum/");
2030		special=(char *)malloc(len);
2031		if(special == NULL) {
2032			errx(1, "malloc failed");
2033		}
2034		snprintf(special, len, "%sr%s", _PATH_DEV, device);
2035		if (stat(special, &st) == -1) {
2036			snprintf(special, len, "%s%s", _PATH_DEV, device);
2037			if (stat(special, &st) == -1) {
2038				snprintf(special, len, "%svinum/r%s",
2039				    _PATH_DEV, device);
2040				if (stat(special, &st) == -1) {
2041					/* For now this is the 'last resort' */
2042					snprintf(special, len, "%svinum/%s",
2043					    _PATH_DEV, device);
2044				}
2045			}
2046		}
2047		device = special;
2048	}
2049
2050	/*
2051	 * Try to access our devices for writing ...
2052	 */
2053	if (Nflag) {
2054		fso = -1;
2055	} else {
2056		fso = open(device, O_WRONLY);
2057		if (fso < 0) {
2058			err(1, "%s", device);
2059		}
2060	}
2061
2062	/*
2063	 * ... and reading.
2064	 */
2065	fsi = open(device, O_RDONLY);
2066	if (fsi < 0) {
2067		err(1, "%s", device);
2068	}
2069
2070	/*
2071	 * Try to read a label and guess the slice if not specified. This
2072	 * code should guess the right thing and avoid to bother the user
2073	 * with the task of specifying the option -v on vinum volumes.
2074	 */
2075	cp=device+strlen(device)-1;
2076	lp = get_disklabel(fsi);
2077	pp = NULL;
2078    if (lp != NULL) {
2079        if (isdigit(*cp)) {
2080            pp = &lp->d_partitions[2];
2081        } else if (*cp>='a' && *cp<='h') {
2082            pp = &lp->d_partitions[*cp - 'a'];
2083        } else {
2084            errx(1, "unknown device");
2085        }
2086        p_size = pp->p_size;
2087    } else {
2088        get_dev_size(fsi, &p_size);
2089    }
2090
2091	/*
2092	 * Check if that partition is suitable for growing a file system.
2093	 */
2094	if (p_size < 1) {
2095		errx(1, "partition is unavailable");
2096	}
2097
2098	/*
2099	 * Read the current superblock, and take a backup.
2100	 */
2101	for (i = 0; sblock_try[i] != -1; i++) {
2102		sblockloc = sblock_try[i] / DEV_BSIZE;
2103		rdfs(sblockloc, (size_t)SBLOCKSIZE, (void *)&(osblock), fsi);
2104		if ((osblock.fs_magic == FS_UFS1_MAGIC ||
2105		     (osblock.fs_magic == FS_UFS2_MAGIC &&
2106		      osblock.fs_sblockloc == sblock_try[i])) &&
2107		    osblock.fs_bsize <= MAXBSIZE &&
2108		    osblock.fs_bsize >= (int32_t) sizeof(struct fs))
2109			break;
2110	}
2111	if (sblock_try[i] == -1) {
2112		errx(1, "superblock not recognized");
2113	}
2114	memcpy((void *)&fsun1, (void *)&fsun2, sizeof(fsun2));
2115	maxino = sblock.fs_ncg * sblock.fs_ipg;
2116
2117	DBG_OPEN("/tmp/growfs.debug"); /* already here we need a superblock */
2118	DBG_DUMP_FS(&sblock,
2119	    "old sblock");
2120
2121	/*
2122	 * Determine size to grow to. Default to the full size specified in
2123	 * the disk label.
2124	 */
2125	sblock.fs_size = dbtofsb(&osblock, p_size);
2126	if (size != 0) {
2127		if (size > p_size){
2128			errx(1, "there is not enough space (%d < %d)",
2129			    p_size, size);
2130		}
2131		sblock.fs_size = dbtofsb(&osblock, size);
2132	}
2133
2134	/*
2135	 * Are we really growing ?
2136	 */
2137	if(osblock.fs_size >= sblock.fs_size) {
2138		errx(1, "we are not growing (%jd->%jd)",
2139		    (intmax_t)osblock.fs_size, (intmax_t)sblock.fs_size);
2140	}
2141
2142
2143#ifdef FSMAXSNAP
2144	/*
2145	 * Check if we find an active snapshot.
2146	 */
2147	if(ExpertFlag == 0) {
2148		for(j=0; j<FSMAXSNAP; j++) {
2149			if(sblock.fs_snapinum[j]) {
2150				errx(1, "active snapshot found in file system\n"
2151				    "	please remove all snapshots before "
2152				    "using growfs");
2153			}
2154			if(!sblock.fs_snapinum[j]) { /* list is dense */
2155				break;
2156			}
2157		}
2158	}
2159#endif
2160
2161	if (ExpertFlag == 0 && Nflag == 0) {
2162		printf("We strongly recommend you to make a backup "
2163		    "before growing the Filesystem\n\n"
2164		    " Did you backup your data (Yes/No) ? ");
2165		fgets(reply, (int)sizeof(reply), stdin);
2166		if (strcmp(reply, "Yes\n")){
2167			printf("\n Nothing done \n");
2168			exit (0);
2169		}
2170	}
2171
2172	printf("new file systemsize is: %jd frags\n", (intmax_t)sblock.fs_size);
2173
2174	/*
2175	 * Try to access our new last block in the file system. Even if we
2176	 * later on realize we have to abort our operation, on that block
2177	 * there should be no data, so we can't destroy something yet.
2178	 */
2179	wtfs((ufs2_daddr_t)p_size-1, (size_t)DEV_BSIZE, (void *)&sblock,
2180	    fso, Nflag);
2181
2182	/*
2183	 * Now calculate new superblock values and check for reasonable
2184	 * bound for new file system size:
2185	 *     fs_size:    is derived from label or user input
2186	 *     fs_dsize:   should get updated in the routines creating or
2187	 *                 updating the cylinder groups on the fly
2188	 *     fs_cstotal: should get updated in the routines creating or
2189	 *                 updating the cylinder groups
2190	 */
2191
2192	/*
2193	 * Update the number of cylinders and cylinder groups in the file system.
2194	 */
2195	if (sblock.fs_magic == FS_UFS1_MAGIC) {
2196		sblock.fs_old_ncyl =
2197		    sblock.fs_size * sblock.fs_old_nspf / sblock.fs_old_spc;
2198		if (sblock.fs_size * sblock.fs_old_nspf >
2199		    sblock.fs_old_ncyl * sblock.fs_old_spc)
2200			sblock.fs_old_ncyl++;
2201	}
2202	sblock.fs_ncg = howmany(sblock.fs_size, sblock.fs_fpg);
2203	maxino = sblock.fs_ncg * sblock.fs_ipg;
2204
2205	if (sblock.fs_size % sblock.fs_fpg != 0 &&
2206	    sblock.fs_size % sblock.fs_fpg < cgdmin(&sblock, sblock.fs_ncg)) {
2207		/*
2208		 * The space in the new last cylinder group is too small,
2209		 * so revert back.
2210		 */
2211		sblock.fs_ncg--;
2212		if (sblock.fs_magic == FS_UFS1_MAGIC)
2213			sblock.fs_old_ncyl = sblock.fs_ncg * sblock.fs_old_cpg;
2214		printf("Warning: %jd sector(s) cannot be allocated.\n",
2215		    (intmax_t)fsbtodb(&sblock, sblock.fs_size % sblock.fs_fpg));
2216		sblock.fs_size = sblock.fs_ncg * sblock.fs_fpg;
2217		maxino -= sblock.fs_ipg;
2218	}
2219
2220	/*
2221	 * Update the space for the cylinder group summary information in the
2222	 * respective cylinder group data area.
2223	 */
2224	sblock.fs_cssize =
2225	    fragroundup(&sblock, sblock.fs_ncg * sizeof(struct csum));
2226
2227	if(osblock.fs_size >= sblock.fs_size) {
2228		errx(1, "not enough new space");
2229	}
2230
2231	DBG_PRINT0("sblock calculated\n");
2232
2233	/*
2234	 * Ok, everything prepared, so now let's do the tricks.
2235	 */
2236	growfs(fsi, fso, Nflag);
2237
2238	/*
2239	 * Update the disk label.
2240	 */
2241    if (!unlabeled) {
2242        pp->p_fsize = sblock.fs_fsize;
2243        pp->p_frag = sblock.fs_frag;
2244        pp->p_cpg = sblock.fs_fpg;
2245
2246        return_disklabel(fso, lp, Nflag);
2247        DBG_PRINT0("label rewritten\n");
2248    }
2249
2250	close(fsi);
2251	if(fso>-1) close(fso);
2252
2253	DBG_CLOSE;
2254
2255	DBG_LEAVE;
2256	return 0;
2257}
2258
2259/* ************************************************** return_disklabel ***** */
2260/*
2261 * Write the updated disklabel back to disk.
2262 */
2263static void
2264return_disklabel(int fd, struct disklabel *lp, unsigned int Nflag)
2265{
2266	DBG_FUNC("return_disklabel")
2267	u_short	sum;
2268	u_short	*ptr;
2269
2270	DBG_ENTER;
2271
2272	if(!lp) {
2273		DBG_LEAVE;
2274		return;
2275	}
2276	if(!Nflag) {
2277		lp->d_checksum=0;
2278		sum = 0;
2279		ptr=(u_short *)lp;
2280
2281		/*
2282		 * recalculate checksum
2283		 */
2284		while(ptr < (u_short *)&lp->d_partitions[lp->d_npartitions]) {
2285			sum ^= *ptr++;
2286		}
2287		lp->d_checksum=sum;
2288
2289		if (ioctl(fd, DIOCWDINFO, (char *)lp) < 0) {
2290			errx(1, "DIOCWDINFO failed");
2291		}
2292	}
2293	free(lp);
2294
2295	DBG_LEAVE;
2296	return ;
2297}
2298
2299/* ***************************************************** get_disklabel ***** */
2300/*
2301 * Read the disklabel from disk.
2302 */
2303static struct disklabel *
2304get_disklabel(int fd)
2305{
2306	DBG_FUNC("get_disklabel")
2307	static struct	disklabel *lab;
2308
2309	DBG_ENTER;
2310
2311	lab=(struct disklabel *)malloc(sizeof(struct disklabel));
2312	if (!lab)
2313		errx(1, "malloc failed");
2314
2315    if (!ioctl(fd, DIOCGDINFO, (char *)lab))
2316        return (lab);
2317
2318    unlabeled++;
2319
2320	DBG_LEAVE;
2321	return (NULL);
2322}
2323
2324
2325/* ************************************************************* usage ***** */
2326/*
2327 * Dump a line of usage.
2328 */
2329static void
2330usage(void)
2331{
2332	DBG_FUNC("usage")
2333
2334	DBG_ENTER;
2335
2336	fprintf(stderr, "usage: growfs [-Ny] [-s size] special\n");
2337
2338	DBG_LEAVE;
2339	exit(1);
2340}
2341
2342/* *********************************************************** updclst ***** */
2343/*
2344 * This updates most parameters and the bitmap related to cluster. We have to
2345 * assume that sblock, osblock, acg are set up.
2346 */
2347static void
2348updclst(int block)
2349{
2350	DBG_FUNC("updclst")
2351	static int	lcs=0;
2352
2353	DBG_ENTER;
2354
2355	if(sblock.fs_contigsumsize < 1) { /* no clustering */
2356		return;
2357	}
2358	/*
2359	 * update cluster allocation map
2360	 */
2361	setbit(cg_clustersfree(&acg), block);
2362
2363	/*
2364	 * update cluster summary table
2365	 */
2366	if(!lcs) {
2367		/*
2368		 * calculate size for the trailing cluster
2369		 */
2370		for(block--; lcs<sblock.fs_contigsumsize; block--, lcs++ ) {
2371			if(isclr(cg_clustersfree(&acg), block)){
2372				break;
2373			}
2374		}
2375	}
2376	if(lcs < sblock.fs_contigsumsize) {
2377		if(lcs) {
2378			cg_clustersum(&acg)[lcs]--;
2379		}
2380		lcs++;
2381		cg_clustersum(&acg)[lcs]++;
2382	}
2383
2384	DBG_LEAVE;
2385	return;
2386}
2387
2388/* *********************************************************** updrefs ***** */
2389/*
2390 * This updates all references to relocated blocks for the given inode.  The
2391 * inode is given as number within the cylinder group, and the number of the
2392 * cylinder group.
2393 */
2394static void
2395updrefs(int cg, ino_t in, struct gfs_bpp *bp, int fsi, int fso, unsigned int
2396    Nflag)
2397{
2398	DBG_FUNC("updrefs")
2399	ufs_lbn_t	len, lbn, numblks;
2400	ufs2_daddr_t	iptr, blksperindir;
2401	union dinode	*ino;
2402	int		i, mode, inodeupdated;
2403
2404	DBG_ENTER;
2405
2406	ino = ginode(in, fsi, cg);
2407	if (ino == NULL) {
2408		DBG_LEAVE;
2409		return;
2410	}
2411	mode = DIP(ino, di_mode) & IFMT;
2412	if (mode != IFDIR && mode != IFREG && mode != IFLNK) {
2413		DBG_LEAVE;
2414		return; /* only check DIR, FILE, LINK */
2415	}
2416	if (mode == IFLNK &&
2417	    DIP(ino, di_size) < (u_int64_t) sblock.fs_maxsymlinklen) {
2418		DBG_LEAVE;
2419		return;	/* skip short symlinks */
2420	}
2421	numblks = howmany(DIP(ino, di_size), sblock.fs_bsize);
2422	if (numblks == 0) {
2423		DBG_LEAVE;
2424		return;	/* skip empty file */
2425	}
2426	if (DIP(ino, di_blocks) == 0) {
2427		DBG_LEAVE;
2428		return;	/* skip empty swiss cheesy file or old fastlink */
2429	}
2430	DBG_PRINT2("scg checking inode (%d in %d)\n",
2431	    in,
2432	    cg);
2433
2434	/*
2435	 * Check all the blocks.
2436	 */
2437	inodeupdated = 0;
2438	len = numblks < NDADDR ? numblks : NDADDR;
2439	for (i = 0; i < len; i++) {
2440		iptr = DIP(ino, di_db[i]);
2441		if (iptr == 0)
2442			continue;
2443		if (cond_bl_upd(&iptr, bp, fsi, fso, Nflag)) {
2444			DIP_SET(ino, di_db[i], iptr);
2445			inodeupdated++;
2446		}
2447	}
2448	DBG_PRINT0("~~scg direct blocks checked\n");
2449
2450	blksperindir = 1;
2451	len = numblks - NDADDR;
2452	lbn = NDADDR;
2453	for (i = 0; len > 0 && i < NIADDR; i++) {
2454		iptr = DIP(ino, di_ib[i]);
2455		if (iptr == 0)
2456			continue;
2457		if (cond_bl_upd(&iptr, bp, fsi, fso, Nflag)) {
2458			DIP_SET(ino, di_ib[i], iptr);
2459			inodeupdated++;
2460		}
2461		indirchk(blksperindir, lbn, iptr, numblks, bp, fsi, fso, Nflag);
2462		blksperindir *= NINDIR(&sblock);
2463		lbn += blksperindir;
2464		len -= blksperindir;
2465		DBG_PRINT1("scg indirect_%d blocks checked\n", i + 1);
2466	}
2467	if (inodeupdated)
2468		wtfs(inoblk, sblock.fs_bsize, inobuf, fso, Nflag);
2469
2470	DBG_LEAVE;
2471	return;
2472}
2473
2474/*
2475 * Recursively check all the indirect blocks.
2476 */
2477static void
2478indirchk(ufs_lbn_t blksperindir, ufs_lbn_t lbn, ufs2_daddr_t blkno,
2479    ufs_lbn_t lastlbn, struct gfs_bpp *bp, int fsi, int fso, unsigned int Nflag)
2480{
2481	DBG_FUNC("indirchk")
2482	void *ibuf;
2483	int i, last;
2484	ufs2_daddr_t iptr;
2485
2486	DBG_ENTER;
2487
2488	/* read in the indirect block. */
2489	ibuf = malloc(sblock.fs_bsize);
2490	if (!ibuf)
2491		errx(1, "malloc failed");
2492	rdfs(fsbtodb(&sblock, blkno), (size_t)sblock.fs_bsize, ibuf, fsi);
2493	last = howmany(lastlbn - lbn, blksperindir) < NINDIR(&sblock) ?
2494	    howmany(lastlbn - lbn, blksperindir) : NINDIR(&sblock);
2495	for (i = 0; i < last; i++) {
2496		if (sblock.fs_magic == FS_UFS1_MAGIC)
2497			iptr = ((ufs1_daddr_t *)ibuf)[i];
2498		else
2499			iptr = ((ufs2_daddr_t *)ibuf)[i];
2500		if (iptr == 0)
2501			continue;
2502		if (cond_bl_upd(&iptr, bp, fsi, fso, Nflag)) {
2503			if (sblock.fs_magic == FS_UFS1_MAGIC)
2504				((ufs1_daddr_t *)ibuf)[i] = iptr;
2505			else
2506				((ufs2_daddr_t *)ibuf)[i] = iptr;
2507		}
2508		if (blksperindir == 1)
2509			continue;
2510		indirchk(blksperindir / NINDIR(&sblock), lbn + blksperindir * i,
2511		    iptr, lastlbn, bp, fsi, fso, Nflag);
2512	}
2513	free(ibuf);
2514
2515	DBG_LEAVE;
2516	return;
2517}
2518