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