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