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