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