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