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