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