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