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