/* * Initialize a cylinder group. */ void initcg(int cylno, time_t utime) { long blkno, start; uint i, j, d, dlower, dupper; ufs2_daddr_t cbase, dmax; struct ufs1_dinode *dp1; struct ufs2_dinode *dp2; struct csum *cs; /* * Determine block bounds for cylinder group. * Allow space for super block summary information in first * cylinder group. */ cbase = cgbase(&sblock, cylno); dmax = cbase + sblock.fs_fpg; if (dmax > sblock.fs_size) dmax = sblock.fs_size; dlower = cgsblock(&sblock, cylno) - cbase; dupper = cgdmin(&sblock, cylno) - cbase; if (cylno == 0) dupper += howmany(sblock.fs_cssize, sblock.fs_fsize); cs = &fscs[cylno]; memset(&acg, 0, sblock.fs_cgsize); acg.cg_time = utime; acg.cg_magic = CG_MAGIC; acg.cg_cgx = cylno; acg.cg_niblk = sblock.fs_ipg; acg.cg_initediblk = sblock.fs_ipg < 2 * INOPB(&sblock) ? sblock.fs_ipg : 2 * INOPB(&sblock); acg.cg_ndblk = dmax - cbase; if (sblock.fs_contigsumsize > 0) acg.cg_nclusterblks = acg.cg_ndblk / sblock.fs_frag; start = &acg.cg_space[0] - (u_char *)(&acg.cg_firstfield); if (Oflag == 2) { acg.cg_iusedoff = start; } else { acg.cg_old_ncyl = sblock.fs_old_cpg; acg.cg_old_time = acg.cg_time; acg.cg_time = 0; acg.cg_old_niblk = acg.cg_niblk; acg.cg_niblk = 0; acg.cg_initediblk = 0; acg.cg_old_btotoff = start; acg.cg_old_boff = acg.cg_old_btotoff + sblock.fs_old_cpg * sizeof(int32_t); acg.cg_iusedoff = acg.cg_old_boff + sblock.fs_old_cpg * sizeof(u_int16_t); } acg.cg_freeoff = acg.cg_iusedoff + howmany(sblock.fs_ipg, CHAR_BIT); acg.cg_nextfreeoff = acg.cg_freeoff + howmany(sblock.fs_fpg, CHAR_BIT); if (sblock.fs_contigsumsize > 0) { acg.cg_clustersumoff = roundup(acg.cg_nextfreeoff, sizeof(u_int32_t)); acg.cg_clustersumoff -= sizeof(u_int32_t); acg.cg_clusteroff = acg.cg_clustersumoff + (sblock.fs_contigsumsize + 1) * sizeof(u_int32_t); acg.cg_nextfreeoff = acg.cg_clusteroff + howmany(fragstoblks(&sblock, sblock.fs_fpg), CHAR_BIT); } if (acg.cg_nextfreeoff > (unsigned)sblock.fs_cgsize) { printf("Panic: cylinder group too big\n"); exit(37); } acg.cg_cs.cs_nifree += sblock.fs_ipg; if (cylno == 0) for (i = 0; i < (long)ROOTINO; i++) { setbit(cg_inosused(&acg), i); acg.cg_cs.cs_nifree--; } if (cylno > 0) { /* * In cylno 0, beginning space is reserved * for boot and super blocks. */ for (d = 0; d < dlower; d += sblock.fs_frag) { blkno = d / sblock.fs_frag; setblock(&sblock, cg_blksfree(&acg), blkno); if (sblock.fs_contigsumsize > 0) setbit(cg_clustersfree(&acg), blkno); acg.cg_cs.cs_nbfree++; } } if ((i = dupper % sblock.fs_frag)) { acg.cg_frsum[sblock.fs_frag - i]++; for (d = dupper + sblock.fs_frag - i; dupper < d; dupper++) { setbit(cg_blksfree(&acg), dupper); acg.cg_cs.cs_nffree++; } } for (d = dupper; d + sblock.fs_frag <= acg.cg_ndblk; d += sblock.fs_frag) { blkno = d / sblock.fs_frag; setblock(&sblock, cg_blksfree(&acg), blkno); if (sblock.fs_contigsumsize > 0) setbit(cg_clustersfree(&acg), blkno); acg.cg_cs.cs_nbfree++; } if (d < acg.cg_ndblk) { acg.cg_frsum[acg.cg_ndblk - d]++; for (; d < acg.cg_ndblk; d++) { setbit(cg_blksfree(&acg), d); acg.cg_cs.cs_nffree++; } } if (sblock.fs_contigsumsize > 0) { int32_t *sump = cg_clustersum(&acg); u_char *mapp = cg_clustersfree(&acg); int map = *mapp++; int bit = 1; int run = 0; for (i = 0; i < acg.cg_nclusterblks; i++) { if ((map & bit) != 0) run++; else if (run != 0) { if (run > sblock.fs_contigsumsize) run = sblock.fs_contigsumsize; sump[run]++; run = 0; } if ((i & (CHAR_BIT - 1)) != CHAR_BIT - 1) bit <<= 1; else { map = *mapp++; bit = 1; } } if (run != 0) { if (run > sblock.fs_contigsumsize) run = sblock.fs_contigsumsize; sump[run]++; } } *cs = acg.cg_cs; /* * Write out the duplicate super block, the cylinder group map * and two blocks worth of inodes in a single write. */ start = sblock.fs_bsize > SBLOCKSIZE ? sblock.fs_bsize : SBLOCKSIZE; bcopy((char *)&acg, &iobuf[start], sblock.fs_cgsize); start += sblock.fs_bsize; dp1 = (struct ufs1_dinode *)(&iobuf[start]); dp2 = (struct ufs2_dinode *)(&iobuf[start]); for (i = 0; i < acg.cg_initediblk; i++) { if (sblock.fs_magic == FS_UFS1_MAGIC) { dp1->di_gen = newfs_random(); dp1++; } else { dp2->di_gen = newfs_random(); dp2++; } } wtfs(fsbtodb(&sblock, cgsblock(&sblock, cylno)), iobufsize, iobuf); /* * For the old file system, we have to initialize all the inodes. */ if (Oflag == 1) { for (i = 2 * sblock.fs_frag; i < sblock.fs_ipg / INOPF(&sblock); i += sblock.fs_frag) { dp1 = (struct ufs1_dinode *)(&iobuf[start]); for (j = 0; j < INOPB(&sblock); j++) { dp1->di_gen = newfs_random(); dp1++; } wtfs(fsbtodb(&sblock, cgimin(&sblock, cylno) + i), sblock.fs_bsize, &iobuf[start]); } } }
void check(char *file) { int i, j, c; fi = open64(file, 0); if (fi < 0) { (void) fprintf(stderr, "ncheck: cannot open %s\n", file); nerror++; return; } nhent = 0; (void) printf("%s:\n", file); sync(); bread((diskaddr_t)SBLOCK, (char *)&sblock, SBSIZE); if ((sblock.fs_magic != FS_MAGIC) && (sblock.fs_magic != MTB_UFS_MAGIC)) { (void) printf("%s: not a ufs file system\n", file); nerror++; return; } if ((sblock.fs_magic == FS_MAGIC) && ((sblock.fs_version != UFS_EFISTYLE4NONEFI_VERSION_2) && (sblock.fs_version != UFS_VERSION_MIN))) { (void) printf("%s: unrecognized ufs version number %d\n", file, sblock.fs_version); nerror++; return; } if ((sblock.fs_magic == MTB_UFS_MAGIC) && ((sblock.fs_version > MTB_UFS_VERSION_1) || (sblock.fs_version < MTB_UFS_VERSION_MIN))) { (void) printf("%s: unrecognized ufs version number %d\n", file, sblock.fs_version); nerror++; return; } /* If fs is logged, roll the log. */ if (sblock.fs_logbno) { switch (rl_roll_log(file)) { case RL_SUCCESS: /* * Reread the superblock. Rolling the log may have * changed it. */ bread((diskaddr_t)SBLOCK, (char *)&sblock, SBSIZE); break; case RL_SYSERR: (void) printf("Warning: cannot roll log for %s. %s\n", file, strerror(errno)); break; default: (void) printf("Warning: cannot roll log for %s.\n", file); break; } } itab = (struct dinode *)extend_tbl((uchar_t *)itab, &itab_size, (unsigned)(sblock.fs_ipg * sizeof (struct dinode))); if (itab == 0) { (void) fprintf(stderr, "ncheck: not enough memory for itab table\n"); nerror++; return; } hsize = sblock.fs_ipg * sblock.fs_ncg - sblock.fs_cstotal.cs_nifree + 1; htab = (struct htab *)extend_tbl((uchar_t *)htab, &htab_size, (unsigned)(hsize * sizeof (struct htab))); if (htab == 0) { (void) fprintf(stderr, "ncheck: not enough memory for htab table\n"); nerror++; return; } if (!extend_strngtab(AVG_PATH_LEN * hsize)) { (void) printf("not enough memory to allocate tables\n"); nerror++; return; } strngloc = 0; ino = 0; for (c = 0; c < sblock.fs_ncg; c++) { bread(fsbtodb(&sblock, cgimin(&sblock, c)), (char *)itab, (int)(sblock.fs_ipg * sizeof (struct dinode))); for (j = 0; j < sblock.fs_ipg; j++) { if (itab[j].di_smode != 0) { itab[j].di_mode = itab[j].di_smode; if (itab[j].di_suid != UID_LONG) itab[j].di_uid = itab[j].di_suid; if (itab[j].di_sgid != GID_LONG) itab[j].di_gid = itab[j].di_sgid; pass1(&itab[j]); } ino++; } } ilist[ilist_index++].ino = 0; if (ilist_index > MAX_ILIST_INDEX()) extend_ilist(); ino = 0; for (c = 0; c < sblock.fs_ncg; c++) { bread(fsbtodb(&sblock, cgimin(&sblock, c)), (char *)itab, (int)(sblock.fs_ipg * sizeof (struct dinode))); for (j = 0; j < sblock.fs_ipg; j++) { if (itab[j].di_smode != 0) { itab[j].di_mode = itab[j].di_smode; pass2(&itab[j]); } ino++; } } ino = 0; for (c = 0; c < sblock.fs_ncg; c++) { bread(fsbtodb(&sblock, cgimin(&sblock, c)), (char *)itab, (int)(sblock.fs_ipg * sizeof (struct dinode))); for (j = 0; j < sblock.fs_ipg; j++) { if (itab[j].di_smode != 0) { itab[j].di_mode = itab[j].di_smode; pass3(&itab[j]); } ino++; } } (void) close(fi); /* * Clear those elements after inodes specified by "-i" out of * ilist. */ for (i = iflg; i < ilist_index; i++) { ilist[i].ino = 0; } ilist_index = iflg; }
/* * Initialize a cylinder group. */ void initcg(int cylno, time_t utime) { int i, j, d, dlower, dupper, blkno, start; daddr64_t cbase, dmax; struct ufs1_dinode *dp1; struct ufs2_dinode *dp2; struct csum *cs; /* * Determine block bounds for cylinder group. Allow space for * super block summary information in first cylinder group. */ cbase = cgbase(&sblock, cylno); dmax = cbase + sblock.fs_fpg; if (dmax > sblock.fs_size) dmax = sblock.fs_size; if (fsbtodb(&sblock, cgsblock(&sblock, cylno)) + iobufsize / sectorsize > fssize) errx(40, "inode table does not fit in cylinder group"); dlower = cgsblock(&sblock, cylno) - cbase; dupper = cgdmin(&sblock, cylno) - cbase; if (cylno == 0) dupper += howmany(sblock.fs_cssize, sblock.fs_fsize); cs = &fscs[cylno]; memset(&acg, 0, sblock.fs_cgsize); acg.cg_ffs2_time = utime; acg.cg_magic = CG_MAGIC; acg.cg_cgx = cylno; acg.cg_ffs2_niblk = sblock.fs_ipg; acg.cg_initediblk = MIN(sblock.fs_ipg, 2 * INOPB(&sblock)); acg.cg_ndblk = dmax - cbase; start = sizeof(struct cg); if (Oflag <= 1) { /* Hack to maintain compatibility with old fsck. */ if (cylno == sblock.fs_ncg - 1) acg.cg_ncyl = 0; else acg.cg_ncyl = sblock.fs_cpg; acg.cg_time = acg.cg_ffs2_time; acg.cg_ffs2_time = 0; acg.cg_niblk = acg.cg_ffs2_niblk; acg.cg_ffs2_niblk = 0; acg.cg_initediblk = 0; acg.cg_btotoff = start; acg.cg_boff = acg.cg_btotoff + sblock.fs_cpg * sizeof(int32_t); acg.cg_iusedoff = acg.cg_boff + sblock.fs_cpg * sizeof(u_int16_t); } else { acg.cg_iusedoff = start; } acg.cg_freeoff = acg.cg_iusedoff + howmany(sblock.fs_ipg, CHAR_BIT); acg.cg_nextfreeoff = acg.cg_freeoff + howmany(sblock.fs_fpg, CHAR_BIT); if (acg.cg_nextfreeoff > sblock.fs_cgsize) errx(37, "panic: cylinder group too big: %d > %d", acg.cg_nextfreeoff, sblock.fs_cgsize); acg.cg_cs.cs_nifree += sblock.fs_ipg; if (cylno == 0) { for (i = 0; i < ROOTINO; i++) { setbit(cg_inosused(&acg), i); acg.cg_cs.cs_nifree--; } } if (cylno > 0) { /* * In cylno 0, space is reserved for boot and super blocks. */ for (d = 0; d < dlower; d += sblock.fs_frag) { blkno = d / sblock.fs_frag; setblock(&sblock, cg_blksfree(&acg), blkno); acg.cg_cs.cs_nbfree++; if (Oflag <= 1) { cg_blktot(&acg)[cbtocylno(&sblock, d)]++; cg_blks(&sblock, &acg, cbtocylno(&sblock, d)) [cbtorpos(&sblock, d)]++; } } } if ((i = dupper % sblock.fs_frag)) { acg.cg_frsum[sblock.fs_frag - i]++; for (d = dupper + sblock.fs_frag - i; dupper < d; dupper++) { setbit(cg_blksfree(&acg), dupper); acg.cg_cs.cs_nffree++; } } for (d = dupper; d + sblock.fs_frag <= acg.cg_ndblk; d += sblock.fs_frag) { blkno = d / sblock.fs_frag; setblock(&sblock, cg_blksfree(&acg), blkno); acg.cg_cs.cs_nbfree++; if (Oflag <= 1) { cg_blktot(&acg)[cbtocylno(&sblock, d)]++; cg_blks(&sblock, &acg, cbtocylno(&sblock, d)) [cbtorpos(&sblock, d)]++; } } if (d < acg.cg_ndblk) { acg.cg_frsum[acg.cg_ndblk - d]++; for (; d < acg.cg_ndblk; d++) { setbit(cg_blksfree(&acg), d); acg.cg_cs.cs_nffree++; } } *cs = acg.cg_cs; /* * Write out the duplicate superblock, the cylinder group map * and two blocks worth of inodes in a single write. */ start = sblock.fs_bsize > SBLOCKSIZE ? sblock.fs_bsize : SBLOCKSIZE; bcopy((char *)&acg, &iobuf[start], sblock.fs_cgsize); start += sblock.fs_bsize; dp1 = (struct ufs1_dinode *)(&iobuf[start]); dp2 = (struct ufs2_dinode *)(&iobuf[start]); for (i = MIN(sblock.fs_ipg, 2 * INOPB(&sblock)); i != 0; i--) { if (sblock.fs_magic == FS_UFS1_MAGIC) { dp1->di_gen = (u_int32_t)arc4random(); dp1++; } else { dp2->di_gen = (u_int32_t)arc4random(); dp2++; } } wtfs(fsbtodb(&sblock, cgsblock(&sblock, cylno)), iobufsize, iobuf); if (Oflag <= 1) { /* Initialize inodes for FFS1. */ for (i = 2 * sblock.fs_frag; i < sblock.fs_ipg / INOPF(&sblock); i += sblock.fs_frag) { dp1 = (struct ufs1_dinode *)(&iobuf[start]); for (j = 0; j < INOPB(&sblock); j++) { dp1->di_gen = (u_int32_t)arc4random(); dp1++; } wtfs(fsbtodb(&sblock, cgimin(&sblock, cylno) + i), sblock.fs_bsize, &iobuf[start]); } } }
void check(char *file) { int i, j, c; fi = open64(file, 0); if (fi < 0) { (void) fprintf(stderr, "ff: cannot open %s\n", file); nerror++; return; } nhent = 0; (void) printf("%s:\n", file); sync(); bread(SBLOCK, (char *)&sblock, SBSIZE); if ((sblock.fs_magic != FS_MAGIC) && (sblock.fs_magic != MTB_UFS_MAGIC)) { (void) fprintf(stderr, "%s: not a ufs file system\n", file); nerror++; return; } if (sblock.fs_magic == FS_MAGIC && (sblock.fs_version != UFS_EFISTYLE4NONEFI_VERSION_2 && sblock.fs_version != UFS_VERSION_MIN)) { (void) fprintf(stderr, "%s: unrecognized version of UFS: %d\n", file, sblock.fs_version); nerror++; return; } if (sblock.fs_magic == MTB_UFS_MAGIC && (sblock.fs_version > MTB_UFS_VERSION_1 || sblock.fs_version < MTB_UFS_VERSION_MIN)) { (void) fprintf(stderr, "%s: unrecognized version of UFS: %d\n", file, sblock.fs_version); nerror++; return; } /* If fs is logged, roll the log. */ if (sblock.fs_logbno) { switch (rl_roll_log(file)) { case RL_SUCCESS: /* * Reread the superblock. Rolling the log may have * changed it. */ bread(SBLOCK, (char *)&sblock, SBSIZE); break; case RL_SYSERR: (void) printf("Warning: Cannot roll log for %s. %s\n", file, strerror(errno)); break; default: (void) printf("Warning: Cannot roll log for %s.\n ", file); break; } } itab = (struct dinode *)calloc(sblock.fs_ipg, sizeof (struct dinode)); imax = sblock.fs_ncg * sblock.fs_ipg; hsize = sblock.fs_ipg * sblock.fs_ncg - sblock.fs_cstotal.cs_nifree + 1; htab = (struct htab *)calloc(hsize, sizeof (struct htab)); if (!extend_strngtab(AVG_PATH_LEN * hsize)) { (void) printf("not enough memory to allocate tables\n"); nerror++; return; } strngloc = 0; if ((itab == NULL) || (htab == NULL)) { (void) printf("not enough memory to allocate tables\n"); nerror++; return; } ino = 0; for (c = 0; c < sblock.fs_ncg; c++) { bread(fsbtodb(&sblock, cgimin(&sblock, c)), (char *)itab, (int)(sblock.fs_ipg * sizeof (struct dinode))); for (j = 0; j < sblock.fs_ipg; j++) { if (itab[j].di_smode != 0) { itab[j].di_mode = itab[j].di_smode; if (itab[j].di_suid != (o_uid_t)UID_LONG) itab[j].di_uid = (unsigned int)itab[j].di_suid; if (itab[j].di_sgid != GID_LONG) itab[j].di_gid = (unsigned int)itab[j].di_sgid; pass1(&itab[j]); } ino++; } } ilist[nxfile+1].ino = 0; ino = 0; for (c = 0; c < sblock.fs_ncg; c++) { bread(fsbtodb(&sblock, cgimin(&sblock, c)), (char *)itab, (int)(sblock.fs_ipg * sizeof (struct dinode))); for (j = 0; j < sblock.fs_ipg; j++) { if (itab[j].di_smode != 0) { itab[j].di_mode = itab[j].di_smode; pass2(&itab[j]); } ino++; } } ino = 0; for (c = 0; c < sblock.fs_ncg; c++) { bread(fsbtodb(&sblock, cgimin(&sblock, c)), (char *)itab, (int)(sblock.fs_ipg * sizeof (struct dinode))); for (j = 0; j < sblock.fs_ipg; j++) { if (itab[j].di_smode != 0) { itab[j].di_mode = itab[j].di_smode; pass3(&itab[j]); } ino++; } } (void) close(fi); for (i = iflg; i < NB; i++) ilist[i].ino = 0; nxfile = iflg; free(itab); free(htab); free(strngtab); }