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