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