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