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