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