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