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