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