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