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