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