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