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