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