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