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