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