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