1 /*- 2 * SPDX-License-Identifier: BSD-4-Clause 3 * 4 * Copyright (c) 1980, 1989, 1993 The Regents of the University of California. 5 * Copyright (c) 2000 Christoph Herrmann, Thomas-Henning von Kamptz 6 * Copyright (c) 2012 The FreeBSD Foundation 7 * All rights reserved. 8 * 9 * This code is derived from software contributed to Berkeley by 10 * Christoph Herrmann and Thomas-Henning von Kamptz, Munich and Frankfurt. 11 * 12 * Portions of this software were developed by Edward Tomasz Napierala 13 * under sponsorship from the FreeBSD Foundation. 14 * 15 * Redistribution and use in source and binary forms, with or without 16 * modification, are permitted provided that the following conditions 17 * are met: 18 * 1. Redistributions of source code must retain the above copyright 19 * notice, this list of conditions and the following disclaimer. 20 * 2. Redistributions in binary form must reproduce the above copyright 21 * notice, this list of conditions and the following disclaimer in the 22 * documentation and/or other materials provided with the distribution. 23 * 3. All advertising materials mentioning features or use of this software 24 * must display the following acknowledgment: 25 * This product includes software developed by the University of 26 * California, Berkeley and its contributors, as well as Christoph 27 * Herrmann and Thomas-Henning von Kamptz. 28 * 4. Neither the name of the University nor the names of its contributors 29 * may be used to endorse or promote products derived from this software 30 * without specific prior written permission. 31 * 32 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 33 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 34 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 35 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 36 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 40 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 41 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 42 * SUCH DAMAGE. 43 * 44 * $TSHeader: src/sbin/growfs/growfs.c,v 1.5 2000/12/12 19:31:00 tomsoft Exp $ 45 * 46 */ 47 48 #ifndef lint 49 static const char copyright[] = 50 "@(#) Copyright (c) 2000 Christoph Herrmann, Thomas-Henning von Kamptz\n\ 51 Copyright (c) 1980, 1989, 1993 The Regents of the University of California.\n\ 52 All rights reserved.\n"; 53 #endif /* not lint */ 54 55 #include <sys/cdefs.h> 56 __FBSDID("$FreeBSD$"); 57 58 #include <sys/param.h> 59 #include <sys/ioctl.h> 60 #include <sys/stat.h> 61 #include <sys/disk.h> 62 #include <sys/ucred.h> 63 #include <sys/mount.h> 64 65 #include <stdio.h> 66 #include <paths.h> 67 #include <ctype.h> 68 #include <err.h> 69 #include <errno.h> 70 #include <fcntl.h> 71 #include <fstab.h> 72 #include <inttypes.h> 73 #include <limits.h> 74 #include <mntopts.h> 75 #include <paths.h> 76 #include <stdlib.h> 77 #include <stdint.h> 78 #include <string.h> 79 #include <time.h> 80 #include <unistd.h> 81 #include <ufs/ufs/dinode.h> 82 #include <ufs/ffs/fs.h> 83 #include <libutil.h> 84 #include <libufs.h> 85 86 #include "debug.h" 87 88 #ifdef FS_DEBUG 89 int _dbg_lvl_ = (DL_INFO); /* DL_TRC */ 90 #endif /* FS_DEBUG */ 91 92 static union { 93 struct fs fs; 94 char pad[SBLOCKSIZE]; 95 } fsun1, fsun2; 96 #define sblock fsun1.fs /* the new superblock */ 97 #define osblock fsun2.fs /* the old superblock */ 98 99 static union { 100 struct cg cg; 101 char pad[MAXBSIZE]; 102 } cgun1, cgun2; 103 #define acg cgun1.cg /* a cylinder cgroup (new) */ 104 #define aocg cgun2.cg /* an old cylinder group */ 105 106 static struct csum *fscs; /* cylinder summary */ 107 108 static void growfs(int, int, unsigned int); 109 static void rdfs(ufs2_daddr_t, size_t, void *, int); 110 static void wtfs(ufs2_daddr_t, size_t, void *, int, unsigned int); 111 static int charsperline(void); 112 static void usage(void); 113 static int isblock(struct fs *, unsigned char *, int); 114 static void clrblock(struct fs *, unsigned char *, int); 115 static void setblock(struct fs *, unsigned char *, int); 116 static void initcg(int, time_t, int, unsigned int); 117 static void updjcg(int, time_t, int, int, unsigned int); 118 static void updcsloc(time_t, int, int, unsigned int); 119 static void frag_adjust(ufs2_daddr_t, int); 120 static void updclst(int); 121 static void cgckhash(struct cg *); 122 123 /* 124 * Here we actually start growing the file system. We basically read the 125 * cylinder summary from the first cylinder group as we want to update 126 * this on the fly during our various operations. First we handle the 127 * changes in the former last cylinder group. Afterwards we create all new 128 * cylinder groups. Now we handle the cylinder group containing the 129 * cylinder summary which might result in a relocation of the whole 130 * structure. In the end we write back the updated cylinder summary, the 131 * new superblock, and slightly patched versions of the super block 132 * copies. 133 */ 134 static void 135 growfs(int fsi, int fso, unsigned int Nflag) 136 { 137 DBG_FUNC("growfs") 138 time_t modtime; 139 uint cylno; 140 int i, j, width; 141 char tmpbuf[100]; 142 143 DBG_ENTER; 144 145 time(&modtime); 146 147 /* 148 * Get the cylinder summary into the memory. 149 */ 150 fscs = (struct csum *)calloc((size_t)1, (size_t)sblock.fs_cssize); 151 if (fscs == NULL) 152 errx(1, "calloc failed"); 153 memcpy(fscs, osblock.fs_csp, osblock.fs_cssize); 154 free(osblock.fs_csp); 155 osblock.fs_csp = NULL; 156 sblock.fs_csp = fscs; 157 158 #ifdef FS_DEBUG 159 { 160 struct csum *dbg_csp; 161 u_int32_t dbg_csc; 162 char dbg_line[80]; 163 164 dbg_csp = fscs; 165 166 for (dbg_csc = 0; dbg_csc < osblock.fs_ncg; dbg_csc++) { 167 snprintf(dbg_line, sizeof(dbg_line), 168 "%d. old csum in old location", dbg_csc); 169 DBG_DUMP_CSUM(&osblock, dbg_line, dbg_csp++); 170 } 171 } 172 #endif /* FS_DEBUG */ 173 DBG_PRINT0("fscs read\n"); 174 175 /* 176 * Do all needed changes in the former last cylinder group. 177 */ 178 updjcg(osblock.fs_ncg - 1, modtime, fsi, fso, Nflag); 179 180 /* 181 * Dump out summary information about file system. 182 */ 183 #ifdef FS_DEBUG 184 #define B2MBFACTOR (1 / (1024.0 * 1024.0)) 185 printf("growfs: %.1fMB (%jd sectors) block size %d, fragment size %d\n", 186 (float)sblock.fs_size * sblock.fs_fsize * B2MBFACTOR, 187 (intmax_t)fsbtodb(&sblock, sblock.fs_size), sblock.fs_bsize, 188 sblock.fs_fsize); 189 printf("\tusing %d cylinder groups of %.2fMB, %d blks, %d inodes.\n", 190 sblock.fs_ncg, (float)sblock.fs_fpg * sblock.fs_fsize * B2MBFACTOR, 191 sblock.fs_fpg / sblock.fs_frag, sblock.fs_ipg); 192 if (sblock.fs_flags & FS_DOSOFTDEP) 193 printf("\twith soft updates\n"); 194 #undef B2MBFACTOR 195 #endif /* FS_DEBUG */ 196 197 /* 198 * Now build the cylinders group blocks and 199 * then print out indices of cylinder groups. 200 */ 201 printf("super-block backups (for fsck_ffs -b #) at:\n"); 202 i = 0; 203 width = charsperline(); 204 205 /* 206 * Iterate for only the new cylinder groups. 207 */ 208 for (cylno = osblock.fs_ncg; cylno < sblock.fs_ncg; cylno++) { 209 initcg(cylno, modtime, fso, Nflag); 210 j = sprintf(tmpbuf, " %jd%s", 211 (intmax_t)fsbtodb(&sblock, cgsblock(&sblock, cylno)), 212 cylno < (sblock.fs_ncg - 1) ? "," : "" ); 213 if (i + j >= width) { 214 printf("\n"); 215 i = 0; 216 } 217 i += j; 218 printf("%s", tmpbuf); 219 fflush(stdout); 220 } 221 printf("\n"); 222 223 /* 224 * Do all needed changes in the first cylinder group. 225 * allocate blocks in new location 226 */ 227 updcsloc(modtime, fsi, fso, Nflag); 228 229 /* 230 * Clean up the dynamic fields in our superblock. 231 * 232 * XXX 233 * The following fields are currently distributed from the superblock 234 * to the copies: 235 * fs_minfree 236 * fs_rotdelay 237 * fs_maxcontig 238 * fs_maxbpg 239 * fs_minfree, 240 * fs_optim 241 * fs_flags 242 * 243 * We probably should rather change the summary for the cylinder group 244 * statistics here to the value of what would be in there, if the file 245 * system were created initially with the new size. Therefor we still 246 * need to find an easy way of calculating that. 247 * Possibly we can try to read the first superblock copy and apply the 248 * "diffed" stats between the old and new superblock by still copying 249 * certain parameters onto that. 250 */ 251 sblock.fs_time = modtime; 252 sblock.fs_fmod = 0; 253 sblock.fs_clean = 1; 254 sblock.fs_ronly = 0; 255 sblock.fs_cgrotor = 0; 256 sblock.fs_state = 0; 257 memset((void *)&sblock.fs_fsmnt, 0, sizeof(sblock.fs_fsmnt)); 258 259 /* 260 * Now write the new superblock, its summary information, 261 * and all the alternates back to disk. 262 */ 263 if (!Nflag && sbput(fso, &sblock, sblock.fs_ncg) != 0) 264 errc(2, EIO, "could not write updated superblock"); 265 DBG_PRINT0("fscs written\n"); 266 267 #ifdef FS_DEBUG 268 { 269 struct csum *dbg_csp; 270 u_int32_t dbg_csc; 271 char dbg_line[80]; 272 273 dbg_csp = fscs; 274 for (dbg_csc = 0; dbg_csc < sblock.fs_ncg; dbg_csc++) { 275 snprintf(dbg_line, sizeof(dbg_line), 276 "%d. new csum in new location", dbg_csc); 277 DBG_DUMP_CSUM(&sblock, dbg_line, dbg_csp++); 278 } 279 } 280 #endif /* FS_DEBUG */ 281 282 DBG_PRINT0("sblock written\n"); 283 DBG_DUMP_FS(&sblock, "new initial sblock"); 284 285 DBG_PRINT0("sblock copies written\n"); 286 DBG_DUMP_FS(&sblock, "new other sblocks"); 287 288 DBG_LEAVE; 289 return; 290 } 291 292 /* 293 * This creates a new cylinder group structure, for more details please see 294 * the source of newfs(8), as this function is taken over almost unchanged. 295 * As this is never called for the first cylinder group, the special 296 * provisions for that case are removed here. 297 */ 298 static void 299 initcg(int cylno, time_t modtime, int fso, unsigned int Nflag) 300 { 301 DBG_FUNC("initcg") 302 static caddr_t iobuf; 303 static long iobufsize; 304 long blkno, start; 305 ino_t ino; 306 ufs2_daddr_t i, cbase, dmax; 307 struct ufs1_dinode *dp1; 308 struct ufs2_dinode *dp2; 309 struct csum *cs; 310 uint j, d, dupper, dlower; 311 312 if (iobuf == NULL) { 313 iobufsize = 2 * sblock.fs_bsize; 314 if ((iobuf = malloc(iobufsize)) == NULL) 315 errx(37, "panic: cannot allocate I/O buffer"); 316 memset(iobuf, '\0', iobufsize); 317 } 318 /* 319 * Determine block bounds for cylinder group. 320 * Allow space for super block summary information in first 321 * cylinder group. 322 */ 323 cbase = cgbase(&sblock, cylno); 324 dmax = cbase + sblock.fs_fpg; 325 if (dmax > sblock.fs_size) 326 dmax = sblock.fs_size; 327 dlower = cgsblock(&sblock, cylno) - cbase; 328 dupper = cgdmin(&sblock, cylno) - cbase; 329 if (cylno == 0) /* XXX fscs may be relocated */ 330 dupper += howmany(sblock.fs_cssize, sblock.fs_fsize); 331 cs = &fscs[cylno]; 332 memset(&acg, 0, sblock.fs_cgsize); 333 acg.cg_time = modtime; 334 acg.cg_magic = CG_MAGIC; 335 acg.cg_cgx = cylno; 336 acg.cg_niblk = sblock.fs_ipg; 337 acg.cg_initediblk = MIN(sblock.fs_ipg, 2 * INOPB(&sblock)); 338 acg.cg_ndblk = dmax - cbase; 339 if (sblock.fs_contigsumsize > 0) 340 acg.cg_nclusterblks = acg.cg_ndblk / sblock.fs_frag; 341 start = &acg.cg_space[0] - (u_char *)(&acg.cg_firstfield); 342 if (sblock.fs_magic == FS_UFS2_MAGIC) { 343 acg.cg_iusedoff = start; 344 } else { 345 acg.cg_old_ncyl = sblock.fs_old_cpg; 346 acg.cg_old_time = acg.cg_time; 347 acg.cg_time = 0; 348 acg.cg_old_niblk = acg.cg_niblk; 349 acg.cg_niblk = 0; 350 acg.cg_initediblk = 0; 351 acg.cg_old_btotoff = start; 352 acg.cg_old_boff = acg.cg_old_btotoff + 353 sblock.fs_old_cpg * sizeof(int32_t); 354 acg.cg_iusedoff = acg.cg_old_boff + 355 sblock.fs_old_cpg * sizeof(u_int16_t); 356 } 357 acg.cg_freeoff = acg.cg_iusedoff + howmany(sblock.fs_ipg, CHAR_BIT); 358 acg.cg_nextfreeoff = acg.cg_freeoff + howmany(sblock.fs_fpg, CHAR_BIT); 359 if (sblock.fs_contigsumsize > 0) { 360 acg.cg_clustersumoff = 361 roundup(acg.cg_nextfreeoff, sizeof(u_int32_t)); 362 acg.cg_clustersumoff -= sizeof(u_int32_t); 363 acg.cg_clusteroff = acg.cg_clustersumoff + 364 (sblock.fs_contigsumsize + 1) * sizeof(u_int32_t); 365 acg.cg_nextfreeoff = acg.cg_clusteroff + 366 howmany(fragstoblks(&sblock, sblock.fs_fpg), CHAR_BIT); 367 } 368 if (acg.cg_nextfreeoff > (unsigned)sblock.fs_cgsize) { 369 /* 370 * This should never happen as we would have had that panic 371 * already on file system creation 372 */ 373 errx(37, "panic: cylinder group too big"); 374 } 375 acg.cg_cs.cs_nifree += sblock.fs_ipg; 376 if (cylno == 0) 377 for (ino = 0; ino < UFS_ROOTINO; ino++) { 378 setbit(cg_inosused(&acg), ino); 379 acg.cg_cs.cs_nifree--; 380 } 381 /* 382 * Initialize the initial inode blocks. 383 */ 384 dp1 = (struct ufs1_dinode *)(void *)iobuf; 385 dp2 = (struct ufs2_dinode *)(void *)iobuf; 386 for (i = 0; i < acg.cg_initediblk; i++) { 387 if (sblock.fs_magic == FS_UFS1_MAGIC) { 388 dp1->di_gen = arc4random(); 389 dp1++; 390 } else { 391 dp2->di_gen = arc4random(); 392 dp2++; 393 } 394 } 395 wtfs(fsbtodb(&sblock, cgimin(&sblock, cylno)), iobufsize, iobuf, 396 fso, Nflag); 397 /* 398 * For the old file system, we have to initialize all the inodes. 399 */ 400 if (sblock.fs_magic == FS_UFS1_MAGIC && 401 sblock.fs_ipg > 2 * INOPB(&sblock)) { 402 for (i = 2 * sblock.fs_frag; 403 i < sblock.fs_ipg / INOPF(&sblock); 404 i += sblock.fs_frag) { 405 dp1 = (struct ufs1_dinode *)(void *)iobuf; 406 for (j = 0; j < INOPB(&sblock); j++) { 407 dp1->di_gen = arc4random(); 408 dp1++; 409 } 410 wtfs(fsbtodb(&sblock, cgimin(&sblock, cylno) + i), 411 sblock.fs_bsize, iobuf, fso, Nflag); 412 } 413 } 414 if (cylno > 0) { 415 /* 416 * In cylno 0, beginning space is reserved 417 * for boot and super blocks. 418 */ 419 for (d = 0; d < dlower; d += sblock.fs_frag) { 420 blkno = d / sblock.fs_frag; 421 setblock(&sblock, cg_blksfree(&acg), blkno); 422 if (sblock.fs_contigsumsize > 0) 423 setbit(cg_clustersfree(&acg), blkno); 424 acg.cg_cs.cs_nbfree++; 425 } 426 sblock.fs_dsize += dlower; 427 } 428 sblock.fs_dsize += acg.cg_ndblk - dupper; 429 sblock.fs_old_dsize = sblock.fs_dsize; 430 if ((i = dupper % sblock.fs_frag)) { 431 acg.cg_frsum[sblock.fs_frag - i]++; 432 for (d = dupper + sblock.fs_frag - i; dupper < d; dupper++) { 433 setbit(cg_blksfree(&acg), dupper); 434 acg.cg_cs.cs_nffree++; 435 } 436 } 437 for (d = dupper; d + sblock.fs_frag <= acg.cg_ndblk; 438 d += sblock.fs_frag) { 439 blkno = d / sblock.fs_frag; 440 setblock(&sblock, cg_blksfree(&acg), blkno); 441 if (sblock.fs_contigsumsize > 0) 442 setbit(cg_clustersfree(&acg), blkno); 443 acg.cg_cs.cs_nbfree++; 444 } 445 if (d < acg.cg_ndblk) { 446 acg.cg_frsum[acg.cg_ndblk - d]++; 447 for (; d < acg.cg_ndblk; d++) { 448 setbit(cg_blksfree(&acg), d); 449 acg.cg_cs.cs_nffree++; 450 } 451 } 452 if (sblock.fs_contigsumsize > 0) { 453 int32_t *sump = cg_clustersum(&acg); 454 u_char *mapp = cg_clustersfree(&acg); 455 int map = *mapp++; 456 int bit = 1; 457 int run = 0; 458 459 for (i = 0; i < acg.cg_nclusterblks; i++) { 460 if ((map & bit) != 0) 461 run++; 462 else if (run != 0) { 463 if (run > sblock.fs_contigsumsize) 464 run = sblock.fs_contigsumsize; 465 sump[run]++; 466 run = 0; 467 } 468 if ((i & (CHAR_BIT - 1)) != CHAR_BIT - 1) 469 bit <<= 1; 470 else { 471 map = *mapp++; 472 bit = 1; 473 } 474 } 475 if (run != 0) { 476 if (run > sblock.fs_contigsumsize) 477 run = sblock.fs_contigsumsize; 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 487 cgckhash(&acg); 488 wtfs(fsbtodb(&sblock, cgtod(&sblock, cylno)), sblock.fs_cgsize, &acg, 489 fso, Nflag); 490 DBG_DUMP_CG(&sblock, "new cg", &acg); 491 492 DBG_LEAVE; 493 return; 494 } 495 496 /* 497 * Here we add or subtract (sign +1/-1) the available fragments in a given 498 * block to or from the fragment statistics. By subtracting before and adding 499 * after an operation on the free frag map we can easy update the fragment 500 * statistic, which seems to be otherwise a rather complex operation. 501 */ 502 static void 503 frag_adjust(ufs2_daddr_t frag, int sign) 504 { 505 DBG_FUNC("frag_adjust") 506 int fragsize; 507 int f; 508 509 DBG_ENTER; 510 511 fragsize = 0; 512 /* 513 * Here frag only needs to point to any fragment in the block we want 514 * to examine. 515 */ 516 for (f = rounddown(frag, sblock.fs_frag); 517 f < roundup(frag + 1, sblock.fs_frag); f++) { 518 /* 519 * Count contiguous free fragments. 520 */ 521 if (isset(cg_blksfree(&acg), f)) { 522 fragsize++; 523 } else { 524 if (fragsize && fragsize < sblock.fs_frag) { 525 /* 526 * We found something in between. 527 */ 528 acg.cg_frsum[fragsize] += sign; 529 DBG_PRINT2("frag_adjust [%d]+=%d\n", 530 fragsize, sign); 531 } 532 fragsize = 0; 533 } 534 } 535 if (fragsize && fragsize < sblock.fs_frag) { 536 /* 537 * We found something. 538 */ 539 acg.cg_frsum[fragsize] += sign; 540 DBG_PRINT2("frag_adjust [%d]+=%d\n", fragsize, sign); 541 } 542 DBG_PRINT2("frag_adjust [[%d]]+=%d\n", fragsize, sign); 543 544 DBG_LEAVE; 545 return; 546 } 547 548 /* 549 * Here we do all needed work for the former last cylinder group. It has to be 550 * changed in any case, even if the file system ended exactly on the end of 551 * this group, as there is some slightly inconsistent handling of the number 552 * of cylinders in the cylinder group. We start again by reading the cylinder 553 * group from disk. If the last block was not fully available, we first handle 554 * the missing fragments, then we handle all new full blocks in that file 555 * system and finally we handle the new last fragmented block in the file 556 * system. We again have to handle the fragment statistics rotational layout 557 * tables and cluster summary during all those operations. 558 */ 559 static void 560 updjcg(int cylno, time_t modtime, int fsi, int fso, unsigned int Nflag) 561 { 562 DBG_FUNC("updjcg") 563 ufs2_daddr_t cbase, dmax; 564 struct csum *cs; 565 int i, k; 566 int j = 0; 567 568 DBG_ENTER; 569 570 /* 571 * Read the former last (joining) cylinder group from disk, and make 572 * a copy. 573 */ 574 rdfs(fsbtodb(&osblock, cgtod(&osblock, cylno)), 575 (size_t)osblock.fs_cgsize, (void *)&aocg, fsi); 576 DBG_PRINT0("jcg read\n"); 577 DBG_DUMP_CG(&sblock, "old joining cg", &aocg); 578 579 memcpy((void *)&cgun1, (void *)&cgun2, sizeof(cgun2)); 580 581 /* 582 * If the cylinder group had already its new final size almost 583 * nothing is to be done ... except: 584 * For some reason the value of cg_ncyl in the last cylinder group has 585 * to be zero instead of fs_cpg. As this is now no longer the last 586 * cylinder group we have to change that value now to fs_cpg. 587 */ 588 589 if (cgbase(&osblock, cylno + 1) == osblock.fs_size) { 590 if (sblock.fs_magic == FS_UFS1_MAGIC) 591 acg.cg_old_ncyl = sblock.fs_old_cpg; 592 593 cgckhash(&acg); 594 wtfs(fsbtodb(&sblock, cgtod(&sblock, cylno)), 595 (size_t)sblock.fs_cgsize, (void *)&acg, fso, Nflag); 596 DBG_PRINT0("jcg written\n"); 597 DBG_DUMP_CG(&sblock, "new joining cg", &acg); 598 599 DBG_LEAVE; 600 return; 601 } 602 603 /* 604 * Set up some variables needed later. 605 */ 606 cbase = cgbase(&sblock, cylno); 607 dmax = cbase + sblock.fs_fpg; 608 if (dmax > sblock.fs_size) 609 dmax = sblock.fs_size; 610 611 /* 612 * Set pointer to the cylinder summary for our cylinder group. 613 */ 614 cs = fscs + cylno; 615 616 /* 617 * Touch the cylinder group, update all fields in the cylinder group as 618 * needed, update the free space in the superblock. 619 */ 620 acg.cg_time = modtime; 621 if ((unsigned)cylno == sblock.fs_ncg - 1) { 622 /* 623 * This is still the last cylinder group. 624 */ 625 if (sblock.fs_magic == FS_UFS1_MAGIC) 626 acg.cg_old_ncyl = 627 sblock.fs_old_ncyl % sblock.fs_old_cpg; 628 } else { 629 acg.cg_old_ncyl = sblock.fs_old_cpg; 630 } 631 DBG_PRINT2("jcg dbg: %d %u", cylno, sblock.fs_ncg); 632 #ifdef FS_DEBUG 633 if (sblock.fs_magic == FS_UFS1_MAGIC) 634 DBG_PRINT2("%d %u", acg.cg_old_ncyl, sblock.fs_old_cpg); 635 #endif 636 DBG_PRINT0("\n"); 637 acg.cg_ndblk = dmax - cbase; 638 sblock.fs_dsize += acg.cg_ndblk - aocg.cg_ndblk; 639 sblock.fs_old_dsize = sblock.fs_dsize; 640 if (sblock.fs_contigsumsize > 0) 641 acg.cg_nclusterblks = acg.cg_ndblk / sblock.fs_frag; 642 643 /* 644 * Now we have to update the free fragment bitmap for our new free 645 * space. There again we have to handle the fragmentation and also 646 * the rotational layout tables and the cluster summary. This is 647 * also done per fragment for the first new block if the old file 648 * system end was not on a block boundary, per fragment for the new 649 * last block if the new file system end is not on a block boundary, 650 * and per block for all space in between. 651 * 652 * Handle the first new block here if it was partially available 653 * before. 654 */ 655 if (osblock.fs_size % sblock.fs_frag) { 656 if (roundup(osblock.fs_size, sblock.fs_frag) <= 657 sblock.fs_size) { 658 /* 659 * The new space is enough to fill at least this 660 * block 661 */ 662 j = 0; 663 for (i = roundup(osblock.fs_size - cbase, 664 sblock.fs_frag) - 1; i >= osblock.fs_size - cbase; 665 i--) { 666 setbit(cg_blksfree(&acg), i); 667 acg.cg_cs.cs_nffree++; 668 j++; 669 } 670 671 /* 672 * Check if the fragment just created could join an 673 * already existing fragment at the former end of the 674 * file system. 675 */ 676 if (isblock(&sblock, cg_blksfree(&acg), 677 ((osblock.fs_size - cgbase(&sblock, cylno)) / 678 sblock.fs_frag))) { 679 /* 680 * The block is now completely available. 681 */ 682 DBG_PRINT0("block was\n"); 683 acg.cg_frsum[osblock.fs_size % sblock.fs_frag]--; 684 acg.cg_cs.cs_nbfree++; 685 acg.cg_cs.cs_nffree -= sblock.fs_frag; 686 k = rounddown(osblock.fs_size - cbase, 687 sblock.fs_frag); 688 updclst((osblock.fs_size - cbase) / 689 sblock.fs_frag); 690 } else { 691 /* 692 * Lets rejoin a possible partially growed 693 * fragment. 694 */ 695 k = 0; 696 while (isset(cg_blksfree(&acg), i) && 697 (i >= rounddown(osblock.fs_size - cbase, 698 sblock.fs_frag))) { 699 i--; 700 k++; 701 } 702 if (k) 703 acg.cg_frsum[k]--; 704 acg.cg_frsum[k + j]++; 705 } 706 } else { 707 /* 708 * We only grow by some fragments within this last 709 * block. 710 */ 711 for (i = sblock.fs_size - cbase - 1; 712 i >= osblock.fs_size - cbase; i--) { 713 setbit(cg_blksfree(&acg), i); 714 acg.cg_cs.cs_nffree++; 715 j++; 716 } 717 /* 718 * Lets rejoin a possible partially growed fragment. 719 */ 720 k = 0; 721 while (isset(cg_blksfree(&acg), i) && 722 (i >= rounddown(osblock.fs_size - cbase, 723 sblock.fs_frag))) { 724 i--; 725 k++; 726 } 727 if (k) 728 acg.cg_frsum[k]--; 729 acg.cg_frsum[k + j]++; 730 } 731 } 732 733 /* 734 * Handle all new complete blocks here. 735 */ 736 for (i = roundup(osblock.fs_size - cbase, sblock.fs_frag); 737 i + sblock.fs_frag <= dmax - cbase; /* XXX <= or only < ? */ 738 i += sblock.fs_frag) { 739 j = i / sblock.fs_frag; 740 setblock(&sblock, cg_blksfree(&acg), j); 741 updclst(j); 742 acg.cg_cs.cs_nbfree++; 743 } 744 745 /* 746 * Handle the last new block if there are stll some new fragments left. 747 * Here we don't have to bother about the cluster summary or the even 748 * the rotational layout table. 749 */ 750 if (i < (dmax - cbase)) { 751 acg.cg_frsum[dmax - cbase - i]++; 752 for (; i < dmax - cbase; i++) { 753 setbit(cg_blksfree(&acg), i); 754 acg.cg_cs.cs_nffree++; 755 } 756 } 757 758 sblock.fs_cstotal.cs_nffree += 759 (acg.cg_cs.cs_nffree - aocg.cg_cs.cs_nffree); 760 sblock.fs_cstotal.cs_nbfree += 761 (acg.cg_cs.cs_nbfree - aocg.cg_cs.cs_nbfree); 762 /* 763 * The following statistics are not changed here: 764 * sblock.fs_cstotal.cs_ndir 765 * sblock.fs_cstotal.cs_nifree 766 * As the statistics for this cylinder group are ready, copy it to 767 * the summary information array. 768 */ 769 *cs = acg.cg_cs; 770 771 /* 772 * Write the updated "joining" cylinder group back to disk. 773 */ 774 cgckhash(&acg); 775 wtfs(fsbtodb(&sblock, cgtod(&sblock, cylno)), (size_t)sblock.fs_cgsize, 776 (void *)&acg, fso, Nflag); 777 DBG_PRINT0("jcg written\n"); 778 DBG_DUMP_CG(&sblock, "new joining cg", &acg); 779 780 DBG_LEAVE; 781 return; 782 } 783 784 /* 785 * Here we update the location of the cylinder summary. We have two possible 786 * ways of growing the cylinder summary: 787 * (1) We can try to grow the summary in the current location, and relocate 788 * possibly used blocks within the current cylinder group. 789 * (2) Alternatively we can relocate the whole cylinder summary to the first 790 * new completely empty cylinder group. Once the cylinder summary is no 791 * longer in the beginning of the first cylinder group you should never 792 * use a version of fsck which is not aware of the possibility to have 793 * this structure in a non standard place. 794 * Option (2) is considered to be less intrusive to the structure of the file- 795 * system, so that's the one being used. 796 */ 797 static void 798 updcsloc(time_t modtime, int fsi, int fso, unsigned int Nflag) 799 { 800 DBG_FUNC("updcsloc") 801 struct csum *cs; 802 int ocscg, ncscg; 803 ufs2_daddr_t d; 804 int lcs = 0; 805 int block; 806 807 DBG_ENTER; 808 809 if (howmany(sblock.fs_cssize, sblock.fs_fsize) == 810 howmany(osblock.fs_cssize, osblock.fs_fsize)) { 811 /* 812 * No new fragment needed. 813 */ 814 DBG_LEAVE; 815 return; 816 } 817 /* Adjust fs_dsize by added summary blocks */ 818 sblock.fs_dsize -= howmany(sblock.fs_cssize, sblock.fs_fsize) - 819 howmany(osblock.fs_cssize, osblock.fs_fsize); 820 sblock.fs_old_dsize = sblock.fs_dsize; 821 ocscg = dtog(&osblock, osblock.fs_csaddr); 822 cs = fscs + ocscg; 823 824 /* 825 * Read original cylinder group from disk, and make a copy. 826 * XXX If Nflag is set in some very rare cases we now miss 827 * some changes done in updjcg by reading the unmodified 828 * block from disk. 829 */ 830 rdfs(fsbtodb(&osblock, cgtod(&osblock, ocscg)), 831 (size_t)osblock.fs_cgsize, (void *)&aocg, fsi); 832 DBG_PRINT0("oscg read\n"); 833 DBG_DUMP_CG(&sblock, "old summary cg", &aocg); 834 835 memcpy((void *)&cgun1, (void *)&cgun2, sizeof(cgun2)); 836 837 /* 838 * Touch the cylinder group, set up local variables needed later 839 * and update the superblock. 840 */ 841 acg.cg_time = modtime; 842 843 /* 844 * XXX In the case of having active snapshots we may need much more 845 * blocks for the copy on write. We need each block twice, and 846 * also up to 8*3 blocks for indirect blocks for all possible 847 * references. 848 */ 849 /* 850 * There is not enough space in the old cylinder group to 851 * relocate all blocks as needed, so we relocate the whole 852 * cylinder group summary to a new group. We try to use the 853 * first complete new cylinder group just created. Within the 854 * cylinder group we align the area immediately after the 855 * cylinder group information location in order to be as 856 * close as possible to the original implementation of ffs. 857 * 858 * First we have to make sure we'll find enough space in the 859 * new cylinder group. If not, then we currently give up. 860 * We start with freeing everything which was used by the 861 * fragments of the old cylinder summary in the current group. 862 * Now we write back the group meta data, read in the needed 863 * meta data from the new cylinder group, and start allocating 864 * within that group. Here we can assume, the group to be 865 * completely empty. Which makes the handling of fragments and 866 * clusters a lot easier. 867 */ 868 DBG_TRC; 869 if (sblock.fs_ncg - osblock.fs_ncg < 2) 870 errx(2, "panic: not enough space"); 871 872 /* 873 * Point "d" to the first fragment not used by the cylinder 874 * summary. 875 */ 876 d = osblock.fs_csaddr + (osblock.fs_cssize / osblock.fs_fsize); 877 878 /* 879 * Set up last cluster size ("lcs") already here. Calculate 880 * the size for the trailing cluster just behind where "d" 881 * points to. 882 */ 883 if (sblock.fs_contigsumsize > 0) { 884 for (block = howmany(d % sblock.fs_fpg, sblock.fs_frag), 885 lcs = 0; lcs < sblock.fs_contigsumsize; block++, lcs++) { 886 if (isclr(cg_clustersfree(&acg), block)) 887 break; 888 } 889 } 890 891 /* 892 * Point "d" to the last frag used by the cylinder summary. 893 */ 894 d--; 895 896 DBG_PRINT1("d=%jd\n", (intmax_t)d); 897 if ((d + 1) % sblock.fs_frag) { 898 /* 899 * The end of the cylinder summary is not a complete 900 * block. 901 */ 902 DBG_TRC; 903 frag_adjust(d % sblock.fs_fpg, -1); 904 for (; (d + 1) % sblock.fs_frag; d--) { 905 DBG_PRINT1("d=%jd\n", (intmax_t)d); 906 setbit(cg_blksfree(&acg), d % sblock.fs_fpg); 907 acg.cg_cs.cs_nffree++; 908 sblock.fs_cstotal.cs_nffree++; 909 } 910 /* 911 * Point "d" to the last fragment of the last 912 * (incomplete) block of the cylinder summary. 913 */ 914 d++; 915 frag_adjust(d % sblock.fs_fpg, 1); 916 917 if (isblock(&sblock, cg_blksfree(&acg), 918 (d % sblock.fs_fpg) / sblock.fs_frag)) { 919 DBG_PRINT1("d=%jd\n", (intmax_t)d); 920 acg.cg_cs.cs_nffree -= sblock.fs_frag; 921 acg.cg_cs.cs_nbfree++; 922 sblock.fs_cstotal.cs_nffree -= sblock.fs_frag; 923 sblock.fs_cstotal.cs_nbfree++; 924 if (sblock.fs_contigsumsize > 0) { 925 setbit(cg_clustersfree(&acg), 926 (d % sblock.fs_fpg) / sblock.fs_frag); 927 if (lcs < sblock.fs_contigsumsize) { 928 if (lcs) 929 cg_clustersum(&acg)[lcs]--; 930 lcs++; 931 cg_clustersum(&acg)[lcs]++; 932 } 933 } 934 } 935 /* 936 * Point "d" to the first fragment of the block before 937 * the last incomplete block. 938 */ 939 d--; 940 } 941 942 DBG_PRINT1("d=%jd\n", (intmax_t)d); 943 for (d = rounddown(d, sblock.fs_frag); d >= osblock.fs_csaddr; 944 d -= sblock.fs_frag) { 945 DBG_TRC; 946 DBG_PRINT1("d=%jd\n", (intmax_t)d); 947 setblock(&sblock, cg_blksfree(&acg), 948 (d % sblock.fs_fpg) / sblock.fs_frag); 949 acg.cg_cs.cs_nbfree++; 950 sblock.fs_cstotal.cs_nbfree++; 951 if (sblock.fs_contigsumsize > 0) { 952 setbit(cg_clustersfree(&acg), 953 (d % sblock.fs_fpg) / sblock.fs_frag); 954 /* 955 * The last cluster size is already set up. 956 */ 957 if (lcs < sblock.fs_contigsumsize) { 958 if (lcs) 959 cg_clustersum(&acg)[lcs]--; 960 lcs++; 961 cg_clustersum(&acg)[lcs]++; 962 } 963 } 964 } 965 *cs = acg.cg_cs; 966 967 /* 968 * Now write the former cylinder group containing the cylinder 969 * summary back to disk. 970 */ 971 cgckhash(&acg); 972 wtfs(fsbtodb(&sblock, cgtod(&sblock, ocscg)), 973 (size_t)sblock.fs_cgsize, (void *)&acg, fso, Nflag); 974 DBG_PRINT0("oscg written\n"); 975 DBG_DUMP_CG(&sblock, "old summary cg", &acg); 976 977 /* 978 * Find the beginning of the new cylinder group containing the 979 * cylinder summary. 980 */ 981 sblock.fs_csaddr = cgdmin(&sblock, osblock.fs_ncg); 982 ncscg = dtog(&sblock, sblock.fs_csaddr); 983 cs = fscs + ncscg; 984 985 /* 986 * If Nflag is specified, we would now read random data instead 987 * of an empty cg structure from disk. So we can't simulate that 988 * part for now. 989 */ 990 if (Nflag) { 991 DBG_PRINT0("nscg update skipped\n"); 992 DBG_LEAVE; 993 return; 994 } 995 996 /* 997 * Read the future cylinder group containing the cylinder 998 * summary from disk, and make a copy. 999 */ 1000 rdfs(fsbtodb(&sblock, cgtod(&sblock, ncscg)), 1001 (size_t)sblock.fs_cgsize, (void *)&aocg, fsi); 1002 DBG_PRINT0("nscg read\n"); 1003 DBG_DUMP_CG(&sblock, "new summary cg", &aocg); 1004 1005 memcpy((void *)&cgun1, (void *)&cgun2, sizeof(cgun2)); 1006 1007 /* 1008 * Allocate all complete blocks used by the new cylinder 1009 * summary. 1010 */ 1011 for (d = sblock.fs_csaddr; d + sblock.fs_frag <= 1012 sblock.fs_csaddr + (sblock.fs_cssize / sblock.fs_fsize); 1013 d += sblock.fs_frag) { 1014 clrblock(&sblock, cg_blksfree(&acg), 1015 (d % sblock.fs_fpg) / sblock.fs_frag); 1016 acg.cg_cs.cs_nbfree--; 1017 sblock.fs_cstotal.cs_nbfree--; 1018 if (sblock.fs_contigsumsize > 0) { 1019 clrbit(cg_clustersfree(&acg), 1020 (d % sblock.fs_fpg) / sblock.fs_frag); 1021 } 1022 } 1023 1024 /* 1025 * Allocate all fragments used by the cylinder summary in the 1026 * last block. 1027 */ 1028 if (d < sblock.fs_csaddr + (sblock.fs_cssize / sblock.fs_fsize)) { 1029 for (; d - sblock.fs_csaddr < 1030 sblock.fs_cssize/sblock.fs_fsize; d++) { 1031 clrbit(cg_blksfree(&acg), d % sblock.fs_fpg); 1032 acg.cg_cs.cs_nffree--; 1033 sblock.fs_cstotal.cs_nffree--; 1034 } 1035 acg.cg_cs.cs_nbfree--; 1036 acg.cg_cs.cs_nffree += sblock.fs_frag; 1037 sblock.fs_cstotal.cs_nbfree--; 1038 sblock.fs_cstotal.cs_nffree += sblock.fs_frag; 1039 if (sblock.fs_contigsumsize > 0) 1040 clrbit(cg_clustersfree(&acg), 1041 (d % sblock.fs_fpg) / sblock.fs_frag); 1042 1043 frag_adjust(d % sblock.fs_fpg, 1); 1044 } 1045 /* 1046 * XXX Handle the cluster statistics here in the case this 1047 * cylinder group is now almost full, and the remaining 1048 * space is less then the maximum cluster size. This is 1049 * probably not needed, as you would hardly find a file 1050 * system which has only MAXCSBUFS+FS_MAXCONTIG of free 1051 * space right behind the cylinder group information in 1052 * any new cylinder group. 1053 */ 1054 1055 /* 1056 * Update our statistics in the cylinder summary. 1057 */ 1058 *cs = acg.cg_cs; 1059 1060 /* 1061 * Write the new cylinder group containing the cylinder summary 1062 * back to disk. 1063 */ 1064 cgckhash(&acg); 1065 wtfs(fsbtodb(&sblock, cgtod(&sblock, ncscg)), 1066 (size_t)sblock.fs_cgsize, (void *)&acg, fso, Nflag); 1067 DBG_PRINT0("nscg written\n"); 1068 DBG_DUMP_CG(&sblock, "new summary cg", &acg); 1069 1070 DBG_LEAVE; 1071 return; 1072 } 1073 1074 /* 1075 * Here we read some block(s) from disk. 1076 */ 1077 static void 1078 rdfs(ufs2_daddr_t bno, size_t size, void *bf, int fsi) 1079 { 1080 DBG_FUNC("rdfs") 1081 ssize_t n; 1082 1083 DBG_ENTER; 1084 1085 if (bno < 0) 1086 err(32, "rdfs: attempting to read negative block number"); 1087 if (lseek(fsi, (off_t)bno * DEV_BSIZE, 0) < 0) 1088 err(33, "rdfs: seek error: %jd", (intmax_t)bno); 1089 n = read(fsi, bf, size); 1090 if (n != (ssize_t)size) 1091 err(34, "rdfs: read error: %jd", (intmax_t)bno); 1092 1093 DBG_LEAVE; 1094 return; 1095 } 1096 1097 /* 1098 * Here we write some block(s) to disk. 1099 */ 1100 static void 1101 wtfs(ufs2_daddr_t bno, size_t size, void *bf, int fso, unsigned int Nflag) 1102 { 1103 DBG_FUNC("wtfs") 1104 ssize_t n; 1105 1106 DBG_ENTER; 1107 1108 if (Nflag) { 1109 DBG_LEAVE; 1110 return; 1111 } 1112 if (lseek(fso, (off_t)bno * DEV_BSIZE, SEEK_SET) < 0) 1113 err(35, "wtfs: seek error: %ld", (long)bno); 1114 n = write(fso, bf, size); 1115 if (n != (ssize_t)size) 1116 err(36, "wtfs: write error: %ld", (long)bno); 1117 1118 DBG_LEAVE; 1119 return; 1120 } 1121 1122 /* 1123 * Here we check if all frags of a block are free. For more details again 1124 * please see the source of newfs(8), as this function is taken over almost 1125 * unchanged. 1126 */ 1127 static int 1128 isblock(struct fs *fs, unsigned char *cp, int h) 1129 { 1130 DBG_FUNC("isblock") 1131 unsigned char mask; 1132 1133 DBG_ENTER; 1134 1135 switch (fs->fs_frag) { 1136 case 8: 1137 DBG_LEAVE; 1138 return (cp[h] == 0xff); 1139 case 4: 1140 mask = 0x0f << ((h & 0x1) << 2); 1141 DBG_LEAVE; 1142 return ((cp[h >> 1] & mask) == mask); 1143 case 2: 1144 mask = 0x03 << ((h & 0x3) << 1); 1145 DBG_LEAVE; 1146 return ((cp[h >> 2] & mask) == mask); 1147 case 1: 1148 mask = 0x01 << (h & 0x7); 1149 DBG_LEAVE; 1150 return ((cp[h >> 3] & mask) == mask); 1151 default: 1152 fprintf(stderr, "isblock bad fs_frag %d\n", fs->fs_frag); 1153 DBG_LEAVE; 1154 return (0); 1155 } 1156 } 1157 1158 /* 1159 * Here we allocate a complete block in the block map. For more details again 1160 * please see the source of newfs(8), as this function is taken over almost 1161 * unchanged. 1162 */ 1163 static void 1164 clrblock(struct fs *fs, unsigned char *cp, int h) 1165 { 1166 DBG_FUNC("clrblock") 1167 1168 DBG_ENTER; 1169 1170 switch ((fs)->fs_frag) { 1171 case 8: 1172 cp[h] = 0; 1173 break; 1174 case 4: 1175 cp[h >> 1] &= ~(0x0f << ((h & 0x1) << 2)); 1176 break; 1177 case 2: 1178 cp[h >> 2] &= ~(0x03 << ((h & 0x3) << 1)); 1179 break; 1180 case 1: 1181 cp[h >> 3] &= ~(0x01 << (h & 0x7)); 1182 break; 1183 default: 1184 warnx("clrblock bad fs_frag %d", fs->fs_frag); 1185 break; 1186 } 1187 1188 DBG_LEAVE; 1189 return; 1190 } 1191 1192 /* 1193 * Here we free a complete block in the free block map. For more details again 1194 * please see the source of newfs(8), as this function is taken over almost 1195 * unchanged. 1196 */ 1197 static void 1198 setblock(struct fs *fs, unsigned char *cp, int h) 1199 { 1200 DBG_FUNC("setblock") 1201 1202 DBG_ENTER; 1203 1204 switch (fs->fs_frag) { 1205 case 8: 1206 cp[h] = 0xff; 1207 break; 1208 case 4: 1209 cp[h >> 1] |= (0x0f << ((h & 0x1) << 2)); 1210 break; 1211 case 2: 1212 cp[h >> 2] |= (0x03 << ((h & 0x3) << 1)); 1213 break; 1214 case 1: 1215 cp[h >> 3] |= (0x01 << (h & 0x7)); 1216 break; 1217 default: 1218 warnx("setblock bad fs_frag %d", fs->fs_frag); 1219 break; 1220 } 1221 1222 DBG_LEAVE; 1223 return; 1224 } 1225 1226 /* 1227 * Figure out how many lines our current terminal has. For more details again 1228 * please see the source of newfs(8), as this function is taken over almost 1229 * unchanged. 1230 */ 1231 static int 1232 charsperline(void) 1233 { 1234 DBG_FUNC("charsperline") 1235 int columns; 1236 char *cp; 1237 struct winsize ws; 1238 1239 DBG_ENTER; 1240 1241 columns = 0; 1242 if (ioctl(0, TIOCGWINSZ, &ws) != -1) 1243 columns = ws.ws_col; 1244 if (columns == 0 && (cp = getenv("COLUMNS"))) 1245 columns = atoi(cp); 1246 if (columns == 0) 1247 columns = 80; /* last resort */ 1248 1249 DBG_LEAVE; 1250 return (columns); 1251 } 1252 1253 static int 1254 is_dev(const char *name) 1255 { 1256 struct stat devstat; 1257 1258 if (stat(name, &devstat) != 0) 1259 return (0); 1260 if (!S_ISCHR(devstat.st_mode)) 1261 return (0); 1262 return (1); 1263 } 1264 1265 static const char * 1266 getdev(const char *name, struct statfs *statfsp) 1267 { 1268 static char device[MAXPATHLEN]; 1269 const char *cp; 1270 1271 if (is_dev(name)) 1272 return (name); 1273 1274 cp = strrchr(name, '/'); 1275 if (cp == NULL) { 1276 snprintf(device, sizeof(device), "%s%s", _PATH_DEV, name); 1277 if (is_dev(device)) 1278 return (device); 1279 } 1280 1281 if (statfsp != NULL) 1282 return (statfsp->f_mntfromname); 1283 1284 return (NULL); 1285 } 1286 1287 /* 1288 * growfs(8) is a utility which allows to increase the size of an existing 1289 * ufs file system. Currently this can only be done on unmounted file system. 1290 * It recognizes some command line options to specify the new desired size, 1291 * and it does some basic checkings. The old file system size is determined 1292 * and after some more checks like we can really access the new last block 1293 * on the disk etc. we calculate the new parameters for the superblock. After 1294 * having done this we just call growfs() which will do the work. 1295 * We still have to provide support for snapshots. Therefore we first have to 1296 * understand what data structures are always replicated in the snapshot on 1297 * creation, for all other blocks we touch during our procedure, we have to 1298 * keep the old blocks unchanged somewhere available for the snapshots. If we 1299 * are lucky, then we only have to handle our blocks to be relocated in that 1300 * way. 1301 * Also we have to consider in what order we actually update the critical 1302 * data structures of the file system to make sure, that in case of a disaster 1303 * fsck(8) is still able to restore any lost data. 1304 * The foreseen last step then will be to provide for growing even mounted 1305 * file systems. There we have to extend the mount() system call to provide 1306 * userland access to the file system locking facility. 1307 */ 1308 int 1309 main(int argc, char **argv) 1310 { 1311 DBG_FUNC("main") 1312 struct fs *fs; 1313 const char *device; 1314 struct statfs *statfsp; 1315 uint64_t size = 0; 1316 off_t mediasize; 1317 int error, j, fsi, fso, ch, ret, Nflag = 0, yflag = 0; 1318 char *p, reply[5], oldsizebuf[6], newsizebuf[6]; 1319 void *testbuf; 1320 1321 DBG_ENTER; 1322 1323 while ((ch = getopt(argc, argv, "Ns:vy")) != -1) { 1324 switch(ch) { 1325 case 'N': 1326 Nflag = 1; 1327 break; 1328 case 's': 1329 size = (off_t)strtoumax(optarg, &p, 0); 1330 if (p == NULL || *p == '\0') 1331 size *= DEV_BSIZE; 1332 else if (*p == 'b' || *p == 'B') 1333 ; /* do nothing */ 1334 else if (*p == 'k' || *p == 'K') 1335 size <<= 10; 1336 else if (*p == 'm' || *p == 'M') 1337 size <<= 20; 1338 else if (*p == 'g' || *p == 'G') 1339 size <<= 30; 1340 else if (*p == 't' || *p == 'T') { 1341 size <<= 30; 1342 size <<= 10; 1343 } else 1344 errx(1, "unknown suffix on -s argument"); 1345 break; 1346 case 'v': /* for compatibility to newfs */ 1347 break; 1348 case 'y': 1349 yflag = 1; 1350 break; 1351 case '?': 1352 /* FALLTHROUGH */ 1353 default: 1354 usage(); 1355 } 1356 } 1357 argc -= optind; 1358 argv += optind; 1359 1360 if (argc != 1) 1361 usage(); 1362 1363 /* 1364 * Now try to guess the device name. 1365 */ 1366 statfsp = getmntpoint(*argv); 1367 device = getdev(*argv, statfsp); 1368 if (device == NULL) 1369 errx(1, "cannot find special device for %s", *argv); 1370 1371 fsi = open(device, O_RDONLY); 1372 if (fsi < 0) 1373 err(1, "%s", device); 1374 1375 /* 1376 * Try to guess the slice size if not specified. 1377 */ 1378 if (ioctl(fsi, DIOCGMEDIASIZE, &mediasize) == -1) 1379 err(1,"DIOCGMEDIASIZE"); 1380 1381 /* 1382 * Check if that partition is suitable for growing a file system. 1383 */ 1384 if (mediasize < 1) 1385 errx(1, "partition is unavailable"); 1386 1387 /* 1388 * Read the current superblock, and take a backup. 1389 */ 1390 if ((ret = sbget(fsi, &fs, UFS_STDSB, 0)) != 0) { 1391 switch (ret) { 1392 case ENOENT: 1393 errx(1, "superblock not recognized"); 1394 default: 1395 errc(1, ret, "unable to read superblock"); 1396 } 1397 } 1398 /* 1399 * Check for filesystem that was unclean at mount time. 1400 */ 1401 if ((fs->fs_flags & (FS_UNCLEAN | FS_NEEDSFSCK)) != 0) 1402 errx(1, "%s is not clean - run fsck.\n", *argv); 1403 memcpy(&osblock, fs, fs->fs_sbsize); 1404 free(fs); 1405 memcpy((void *)&fsun1, (void *)&fsun2, osblock.fs_sbsize); 1406 1407 DBG_OPEN("/tmp/growfs.debug"); /* already here we need a superblock */ 1408 DBG_DUMP_FS(&sblock, "old sblock"); 1409 1410 /* 1411 * Determine size to grow to. Default to the device size. 1412 */ 1413 if (size == 0) 1414 size = mediasize; 1415 else { 1416 if (size > (uint64_t)mediasize) { 1417 humanize_number(oldsizebuf, sizeof(oldsizebuf), size, 1418 "B", HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL); 1419 humanize_number(newsizebuf, sizeof(newsizebuf), 1420 mediasize, 1421 "B", HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL); 1422 1423 errx(1, "requested size %s is larger " 1424 "than the available %s", oldsizebuf, newsizebuf); 1425 } 1426 } 1427 1428 /* 1429 * Make sure the new size is a multiple of fs_fsize; /dev/ufssuspend 1430 * only supports fragment-aligned IO requests. 1431 */ 1432 size -= size % osblock.fs_fsize; 1433 1434 if (size <= (uint64_t)(osblock.fs_size * osblock.fs_fsize)) { 1435 humanize_number(oldsizebuf, sizeof(oldsizebuf), 1436 osblock.fs_size * osblock.fs_fsize, 1437 "B", HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL); 1438 humanize_number(newsizebuf, sizeof(newsizebuf), size, 1439 "B", HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL); 1440 1441 if (size == (uint64_t)(osblock.fs_size * osblock.fs_fsize)) 1442 errx(0, "requested size %s is equal to the current " 1443 "filesystem size %s", newsizebuf, oldsizebuf); 1444 errx(1, "requested size %s is smaller than the current " 1445 "filesystem size %s", newsizebuf, oldsizebuf); 1446 } 1447 1448 sblock.fs_old_size = sblock.fs_size = 1449 dbtofsb(&osblock, size / DEV_BSIZE); 1450 sblock.fs_providersize = dbtofsb(&osblock, mediasize / DEV_BSIZE); 1451 1452 /* 1453 * Are we really growing? 1454 */ 1455 if (osblock.fs_size >= sblock.fs_size) { 1456 errx(1, "we are not growing (%jd->%jd)", 1457 (intmax_t)osblock.fs_size, (intmax_t)sblock.fs_size); 1458 } 1459 1460 /* 1461 * Check if we find an active snapshot. 1462 */ 1463 if (yflag == 0) { 1464 for (j = 0; j < FSMAXSNAP; j++) { 1465 if (sblock.fs_snapinum[j]) { 1466 errx(1, "active snapshot found in file system; " 1467 "please remove all snapshots before " 1468 "using growfs"); 1469 } 1470 if (!sblock.fs_snapinum[j]) /* list is dense */ 1471 break; 1472 } 1473 } 1474 1475 if (yflag == 0 && Nflag == 0) { 1476 if (statfsp != NULL && (statfsp->f_flags & MNT_RDONLY) == 0) 1477 printf("Device is mounted read-write; resizing will " 1478 "result in temporary write suspension for %s.\n", 1479 statfsp->f_mntonname); 1480 printf("It's strongly recommended to make a backup " 1481 "before growing the file system.\n" 1482 "OK to grow filesystem on %s", device); 1483 if (statfsp != NULL) 1484 printf(", mounted on %s,", statfsp->f_mntonname); 1485 humanize_number(oldsizebuf, sizeof(oldsizebuf), 1486 osblock.fs_size * osblock.fs_fsize, 1487 "B", HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL); 1488 humanize_number(newsizebuf, sizeof(newsizebuf), 1489 sblock.fs_size * sblock.fs_fsize, 1490 "B", HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL); 1491 printf(" from %s to %s? [yes/no] ", oldsizebuf, newsizebuf); 1492 fflush(stdout); 1493 fgets(reply, (int)sizeof(reply), stdin); 1494 if (strcasecmp(reply, "yes\n")){ 1495 printf("Response other than \"yes\"; aborting\n"); 1496 exit(0); 1497 } 1498 } 1499 1500 /* 1501 * Try to access our device for writing. If it's not mounted, 1502 * or mounted read-only, simply open it; otherwise, use UFS 1503 * suspension mechanism. 1504 */ 1505 if (Nflag) { 1506 fso = -1; 1507 } else { 1508 if (statfsp != NULL && (statfsp->f_flags & MNT_RDONLY) == 0) { 1509 fso = open(_PATH_UFSSUSPEND, O_RDWR); 1510 if (fso == -1) 1511 err(1, "unable to open %s", _PATH_UFSSUSPEND); 1512 error = ioctl(fso, UFSSUSPEND, &statfsp->f_fsid); 1513 if (error != 0) 1514 err(1, "UFSSUSPEND"); 1515 } else { 1516 fso = open(device, O_WRONLY); 1517 if (fso < 0) 1518 err(1, "%s", device); 1519 } 1520 } 1521 1522 /* 1523 * Try to access our new last block in the file system. 1524 */ 1525 testbuf = malloc(sblock.fs_fsize); 1526 if (testbuf == NULL) 1527 err(1, "malloc"); 1528 rdfs((ufs2_daddr_t)((size - sblock.fs_fsize) / DEV_BSIZE), 1529 sblock.fs_fsize, testbuf, fsi); 1530 wtfs((ufs2_daddr_t)((size - sblock.fs_fsize) / DEV_BSIZE), 1531 sblock.fs_fsize, testbuf, fso, Nflag); 1532 free(testbuf); 1533 1534 /* 1535 * Now calculate new superblock values and check for reasonable 1536 * bound for new file system size: 1537 * fs_size: is derived from user input 1538 * fs_dsize: should get updated in the routines creating or 1539 * updating the cylinder groups on the fly 1540 * fs_cstotal: should get updated in the routines creating or 1541 * updating the cylinder groups 1542 */ 1543 1544 /* 1545 * Update the number of cylinders and cylinder groups in the file system. 1546 */ 1547 if (sblock.fs_magic == FS_UFS1_MAGIC) { 1548 sblock.fs_old_ncyl = 1549 sblock.fs_size * sblock.fs_old_nspf / sblock.fs_old_spc; 1550 if (sblock.fs_size * sblock.fs_old_nspf > 1551 sblock.fs_old_ncyl * sblock.fs_old_spc) 1552 sblock.fs_old_ncyl++; 1553 } 1554 sblock.fs_ncg = howmany(sblock.fs_size, sblock.fs_fpg); 1555 1556 /* 1557 * Allocate last cylinder group only if there is enough room 1558 * for at least one data block. 1559 */ 1560 if (sblock.fs_size % sblock.fs_fpg != 0 && 1561 sblock.fs_size <= cgdmin(&sblock, sblock.fs_ncg - 1)) { 1562 humanize_number(oldsizebuf, sizeof(oldsizebuf), 1563 (sblock.fs_size % sblock.fs_fpg) * sblock.fs_fsize, 1564 "B", HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL); 1565 warnx("no room to allocate last cylinder group; " 1566 "leaving %s unused", oldsizebuf); 1567 sblock.fs_ncg--; 1568 if (sblock.fs_magic == FS_UFS1_MAGIC) 1569 sblock.fs_old_ncyl = sblock.fs_ncg * sblock.fs_old_cpg; 1570 sblock.fs_old_size = sblock.fs_size = 1571 sblock.fs_ncg * sblock.fs_fpg; 1572 } 1573 1574 /* 1575 * Update the space for the cylinder group summary information in the 1576 * respective cylinder group data area. 1577 */ 1578 sblock.fs_cssize = 1579 fragroundup(&sblock, sblock.fs_ncg * sizeof(struct csum)); 1580 1581 if (osblock.fs_size >= sblock.fs_size) 1582 errx(1, "not enough new space"); 1583 1584 DBG_PRINT0("sblock calculated\n"); 1585 1586 /* 1587 * Ok, everything prepared, so now let's do the tricks. 1588 */ 1589 growfs(fsi, fso, Nflag); 1590 1591 close(fsi); 1592 if (fso > -1) { 1593 if (statfsp != NULL && (statfsp->f_flags & MNT_RDONLY) == 0) { 1594 error = ioctl(fso, UFSRESUME); 1595 if (error != 0) 1596 err(1, "UFSRESUME"); 1597 } 1598 error = close(fso); 1599 if (error != 0) 1600 err(1, "close"); 1601 if (statfsp != NULL && (statfsp->f_flags & MNT_RDONLY) != 0 && 1602 chkdoreload(statfsp, warn) != 0) 1603 exit(9); 1604 } 1605 1606 DBG_CLOSE; 1607 1608 DBG_LEAVE; 1609 return (0); 1610 } 1611 1612 /* 1613 * Dump a line of usage. 1614 */ 1615 static void 1616 usage(void) 1617 { 1618 DBG_FUNC("usage") 1619 1620 DBG_ENTER; 1621 1622 fprintf(stderr, "usage: growfs [-Ny] [-s size] special | filesystem\n"); 1623 1624 DBG_LEAVE; 1625 exit(1); 1626 } 1627 1628 /* 1629 * This updates most parameters and the bitmap related to cluster. We have to 1630 * assume that sblock, osblock, acg are set up. 1631 */ 1632 static void 1633 updclst(int block) 1634 { 1635 DBG_FUNC("updclst") 1636 static int lcs = 0; 1637 1638 DBG_ENTER; 1639 1640 if (sblock.fs_contigsumsize < 1) /* no clustering */ 1641 return; 1642 /* 1643 * update cluster allocation map 1644 */ 1645 setbit(cg_clustersfree(&acg), block); 1646 1647 /* 1648 * update cluster summary table 1649 */ 1650 if (!lcs) { 1651 /* 1652 * calculate size for the trailing cluster 1653 */ 1654 for (block--; lcs < sblock.fs_contigsumsize; block--, lcs++ ) { 1655 if (isclr(cg_clustersfree(&acg), block)) 1656 break; 1657 } 1658 } 1659 if (lcs < sblock.fs_contigsumsize) { 1660 if (lcs) 1661 cg_clustersum(&acg)[lcs]--; 1662 lcs++; 1663 cg_clustersum(&acg)[lcs]++; 1664 } 1665 1666 DBG_LEAVE; 1667 return; 1668 } 1669 1670 /* 1671 * Calculate the check-hash of the cylinder group. 1672 */ 1673 static void 1674 cgckhash(struct cg *cgp) 1675 { 1676 1677 if ((sblock.fs_metackhash & CK_CYLGRP) == 0) 1678 return; 1679 cgp->cg_ckhash = 0; 1680 cgp->cg_ckhash = calculate_crc32c(~0L, (void *)cgp, sblock.fs_cgsize); 1681 } 1682