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