Example #1
0
struct bufarea *
getfilentry(uint32_t block, int len)
{
	struct bufarea *bp;
	struct file_entry *fp;
	int err;

	if (len > fsbsize) {
		(void) printf(gettext("File entry at %x is too long "
		    "(%d bytes)\n"), block, len);
		len = fsbsize;
	}
	bp = getdatablk((daddr_t)(block + part_start), fsbsize);
	if (bp->b_errs) {
		bp->b_flags &= ~B_INUSE;
		return (NULL);
	}
	/* LINTED */
	fp = (struct file_entry *)bp->b_un.b_buf;
	err = verifytag(&fp->fe_tag, block, &fp->fe_tag, UD_FILE_ENTRY);
	if (err) {
		(void) printf(gettext("Tag error %s or bad file entry, "
		    "tag=%d\n"), tagerrs[err], fp->fe_tag.tag_id);
		bp->b_flags &= ~B_INUSE;
		return (NULL);
	}
	return (bp);
}
Example #2
0
/*
 * Scan each entry in an ea block.
 */
int
eascan(struct inodesc *idesc, struct ufs2_dinode *dp)
{
#if 1
	return (0);
#else
	struct bufarea *bp;
	u_int dsize, n;
	u_char *cp;
	long blksiz;
	char dbuf[DIRBLKSIZ];

	printf("Inode %ju extsize %ju\n",
	   (intmax_t)idesc->id_number, (intmax_t)dp->di_extsize);
	if (dp->di_extsize == 0)
		return 0;
	if (dp->di_extsize <= sblock.fs_fsize)
		blksiz = sblock.fs_fsize;
	else
		blksiz = sblock.fs_bsize;
	printf("blksiz = %ju\n", (intmax_t)blksiz);
	bp = getdatablk(dp->di_extb[0], blksiz);
	cp = (u_char *)bp->b_un.b_buf;
	for (n = 0; n < blksiz; n++) {
		printf("%02x", cp[n]);
		if ((n & 31) == 31)
			printf("\n");
	}
	return (STOP);
#endif
}
Example #3
0
/*
 * Get a directory block.
 * Insure that it is held until another is requested.
 */
static struct bufarea *
getdirblk(ufs2_daddr_t blkno, long size)
{

	if (pdirbp != 0)
		pdirbp->b_flags &= ~B_INUSE;
	pdirbp = getdatablk(blkno, size, BT_DIRDATA);
	return (pdirbp);
}
Example #4
0
/*
 * Recursively print a list of indirect blocks.
 */
static void
printindir(ufs2_daddr_t blk, int level, char *bufp)
{
    struct bufarea buf, *bp;
    char tempbuf[32];		/* enough to print an ufs2_daddr_t */
    int i, j, cpl, charssofar;
    ufs2_daddr_t blkno;

    if (blk == 0)
	return;
    printf("%jd (%d) =>\n", (intmax_t)blk, level);
    if (level == 0) {
	/* for the final indirect level, don't use the cache */
	bp = &buf;
	bp->b_un.b_buf = bufp;
	bp->b_prev = bp->b_next = bp;
	initbarea(bp);

	getblk(bp, blk, sblock.fs_bsize);
    } else
	bp = getdatablk(blk, sblock.fs_bsize);

    cpl = charsperline();
    for (i = charssofar = 0; i < NINDIR(&sblock); i++) {
	if (sblock.fs_magic == FS_UFS1_MAGIC)
		blkno = bp->b_un.b_indir1[i];
	else
		blkno = bp->b_un.b_indir2[i];
	if (blkno == 0)
	    continue;
	j = sprintf(tempbuf, "%jd", (intmax_t)blkno);
	if (level == 0) {
	    charssofar += j;
	    if (charssofar >= cpl - 2) {
		putchar('\n');
		charssofar = j;
	    }
	}
	fputs(tempbuf, stdout);
	if (level == 0) {
	    printf(", ");
	    charssofar += 2;
	} else {
	    printf(" =>\n");
	    printindir(blkno, level - 1, bufp);
	    printf("\n");
	    charssofar = 0;
	}
    }
    if (level == 0)
	putchar('\n');
    return;
}
Example #5
0
/*
 * Recursively print a list of indirect blocks.
 */
static int
printindir(ufs_daddr_t blk, int level, char *bufp)
{
    struct bufarea buf, *bp;
    char tempbuf[32];		/* enough to print an ufs_daddr_t */
    int i, j, cpl, charssofar;
    ufs_daddr_t blkno;

    if (level == 0) {
	/* for the final indirect level, don't use the cache */
	bp = &buf;
	bp->b_un.b_buf = bufp;
	bp->b_prev = bp->b_next = bp;
	initbarea(bp);

	getblk(bp, blk, sblock.fs_bsize);
    } else
	bp = getdatablk(blk, sblock.fs_bsize);

    cpl = charsperline();
    for (i = charssofar = 0; i < NINDIR(&sblock); i++) {
	blkno = bp->b_un.b_indir[i];
	if (blkno == 0) {
	    if (level == 0)
		putchar('\n');
	    return 0;
	}
	j = sprintf(tempbuf, "%d", blkno);
	if (level == 0) {
	    charssofar += j;
	    if (charssofar >= cpl - 2) {
		putchar('\n');
		charssofar = j;
	    }
	}
	fputs(tempbuf, stdout);
	if (level == 0) {
	    printf(", ");
	    charssofar += 2;
	} else {
	    printf(" =>\n");
	    if (printindir(blkno, level - 1, bufp) == 0)
		return 0;
	}
    }
    if (level == 0)
	putchar('\n');
    return 1;
}
Example #6
0
/*
 * General purpose interface for reading inodes.
 */
struct ufs1_dinode *
ginode(ufs1_ino_t inumber)
{
	ufs_daddr_t iblk;

	if (inumber < ROOTINO || inumber > maxino)
		errx(EEXIT, "bad inode number %d to ginode", inumber);
	if (startinum == 0 ||
	    inumber < startinum || inumber >= startinum + INOPB(&sblock)) {
		iblk = ino_to_fsba(&sblock, inumber);
		if (pbp != 0)
			pbp->b_flags &= ~B_INUSE;
		pbp = getdatablk(iblk, sblock.fs_bsize);
		startinum = (inumber / INOPB(&sblock)) * INOPB(&sblock);
	}
	return (&pbp->b_un.b_dinode[inumber % INOPB(&sblock)]);
}
Example #7
0
/*
 * General purpose interface for reading inodes.
 */
union dinode *
ginode(ino_t inumber)
{
	ufs2_daddr_t iblk;

	if (inumber < ROOTINO || inumber > maxino)
		errx(EEXIT, "bad inode number %ju to ginode",
		    (uintmax_t)inumber);
	if (startinum == 0 ||
	    inumber < startinum || inumber >= startinum + INOPB(&sblock)) {
		iblk = ino_to_fsba(&sblock, inumber);
		if (pbp != NULL)
			pbp->b_flags &= ~B_INUSE;
		pbp = getdatablk(iblk, sblock.fs_bsize, BT_INODES);
		startinum = rounddown(inumber, INOPB(&sblock));
	}
	if (sblock.fs_magic == FS_UFS1_MAGIC)
		return ((union dinode *)
		    &pbp->b_un.b_dinode1[inumber % INOPB(&sblock)]);
	return ((union dinode *)&pbp->b_un.b_dinode2[inumber % INOPB(&sblock)]);
}
Example #8
0
static int
iblock(struct inodesc *idesc, long ilevel, quad_t isize)
{
	ufs_daddr_t *ap;
	ufs_daddr_t *aplim;
	struct bufarea *bp;
	int i, n, (*func)(), nif;
	quad_t sizepb;
	char buf[BUFSIZ];
	char pathbuf[MAXPATHLEN + 1];
	struct ufs1_dinode *dp;

	if (idesc->id_type == ADDR) {
		func = idesc->id_func;
		if (((n = (*func)(idesc)) & KEEPON) == 0)
			return (n);
	} else
		func = dirscan;
	if (chkrange(idesc->id_blkno, idesc->id_numfrags))
		return (SKIP);
	bp = getdatablk(idesc->id_blkno, sblock.fs_bsize);
	ilevel--;
	for (sizepb = sblock.fs_bsize, i = 0; i < ilevel; i++)
		sizepb *= NINDIR(&sblock);
	nif = howmany(isize , sizepb);
	if (nif > NINDIR(&sblock))
		nif = NINDIR(&sblock);
	if (idesc->id_func == pass1check && nif < NINDIR(&sblock)) {
		aplim = &bp->b_un.b_indir[NINDIR(&sblock)];
		for (ap = &bp->b_un.b_indir[nif]; ap < aplim; ap++) {
			if (*ap == 0)
				continue;
			sprintf(buf, "PARTIALLY TRUNCATED INODE I=%lu",
			    (u_long)idesc->id_number);
			if (dofix(idesc, buf)) {
				*ap = 0;
				dirty(bp);
			}
		}
		flush(fswritefd, bp);
	}
	aplim = &bp->b_un.b_indir[nif];
	for (ap = bp->b_un.b_indir; ap < aplim; ap++) {
		if (*ap) {
			idesc->id_blkno = *ap;
			if (ilevel == 0)
				n = (*func)(idesc);
			else
				n = iblock(idesc, ilevel, isize);
			if (n & STOP) {
				bp->b_flags &= ~B_INUSE;
				return (n);
			}
		} else {
			if (idesc->id_type == DATA && isize > 0) {
				/* An empty block in a directory XXX */
				getpathname(pathbuf, idesc->id_number,
						idesc->id_number);
                        	pfatal("DIRECTORY %s: CONTAINS EMPTY BLOCKS",
					pathbuf);
                        	if (reply("ADJUST LENGTH") == 1) {
					dp = ginode(idesc->id_number);
                                	dp->di_size -= isize;
					isize = 0;
					printf(
					    "YOU MUST RERUN FSCK AFTERWARDS\n");
					rerun = 1;
                                	inodirty();
					bp->b_flags &= ~B_INUSE;
					return(STOP);
                        	}
			}
		}
		isize -= sizepb;
	}
	bp->b_flags &= ~B_INUSE;
	return (KEEPON);
}
Example #9
0
static int
iblock(struct inodesc *idesc, long ilevel, off_t isize, int type)
{
	struct bufarea *bp;
	int i, n, (*func)(struct inodesc *), nif;
	off_t sizepb;
	char buf[BUFSIZ];
	char pathbuf[MAXPATHLEN + 1];
	union dinode *dp;

	if (idesc->id_type != DATA) {
		func = idesc->id_func;
		if (((n = (*func)(idesc)) & KEEPON) == 0)
			return (n);
	} else
		func = dirscan;
	if (chkrange(idesc->id_blkno, idesc->id_numfrags))
		return (SKIP);
	bp = getdatablk(idesc->id_blkno, sblock.fs_bsize, type);
	ilevel--;
	for (sizepb = sblock.fs_bsize, i = 0; i < ilevel; i++)
		sizepb *= NINDIR(&sblock);
	if (howmany(isize, sizepb) > NINDIR(&sblock))
		nif = NINDIR(&sblock);
	else
		nif = howmany(isize, sizepb);
	if (idesc->id_func == pass1check && nif < NINDIR(&sblock)) {
		for (i = nif; i < NINDIR(&sblock); i++) {
			if (IBLK(bp, i) == 0)
				continue;
			(void)sprintf(buf, "PARTIALLY TRUNCATED INODE I=%lu",
			    (u_long)idesc->id_number);
			if (preen) {
				pfatal("%s", buf);
			} else if (dofix(idesc, buf)) {
				IBLK_SET(bp, i, 0);
				dirty(bp);
			}
		}
		flush(fswritefd, bp);
	}
	for (i = 0; i < nif; i++) {
		if (ilevel == 0)
			idesc->id_lbn++;
		if (IBLK(bp, i)) {
			idesc->id_blkno = IBLK(bp, i);
			if (ilevel == 0)
				n = (*func)(idesc);
			else
				n = iblock(idesc, ilevel, isize, type);
			if (n & STOP) {
				bp->b_flags &= ~B_INUSE;
				return (n);
			}
		} else {
			if (idesc->id_type == DATA && isize > 0) {
				/* An empty block in a directory XXX */
				getpathname(pathbuf, idesc->id_number,
						idesc->id_number);
				pfatal("DIRECTORY %s: CONTAINS EMPTY BLOCKS",
					pathbuf);
				if (reply("ADJUST LENGTH") == 1) {
					dp = ginode(idesc->id_number);
					DIP_SET(dp, di_size,
					    DIP(dp, di_size) - isize);
					isize = 0;
					printf(
					    "YOU MUST RERUN FSCK AFTERWARDS\n");
					rerun = 1;
					inodirty();
					bp->b_flags &= ~B_INUSE;
					return(STOP);
				}
			}
		}
		isize -= sizepb;
	}
	bp->b_flags &= ~B_INUSE;
	return (KEEPON);
}
Example #10
0
void
pass5(void)
{
	int c;
	struct m_ext2fs *fs = &sblock;
	daddr_t dbase, dmax;
	daddr_t d;
	long i, j;
	struct inodesc idesc[3];
	struct bufarea *ino_bitmap = NULL, *blk_bitmap = NULL;
	char *ibmap, *bbmap;
	u_int32_t cs_ndir, cs_nbfree, cs_nifree;
	char msg[255];

	cs_ndir = 0;
	cs_nbfree = 0;
	cs_nifree = 0;

	ibmap = malloc(fs->e2fs_bsize);
	bbmap = malloc(fs->e2fs_bsize);
	if (ibmap == NULL || bbmap == NULL) {
		errexit("out of memory\n");
	}

	for (c = 0; c < fs->e2fs_ncg; c++) {
		u_int32_t nbfree = 0;
		u_int32_t nifree = 0;
		u_int32_t ndirs = 0;

		nbfree = 0;
		nifree = fs->e2fs.e2fs_ipg;
		ndirs = 0;

		if (blk_bitmap == NULL) {
			blk_bitmap = getdatablk(fs2h32(fs->e2fs_gd[c].ext2bgd_b_bitmap),
				fs->e2fs_bsize);
		} else {
			getblk(blk_bitmap, fs2h32(fs->e2fs_gd[c].ext2bgd_b_bitmap),
				fs->e2fs_bsize);
		}
		if (ino_bitmap == NULL) {
			ino_bitmap = getdatablk(fs2h32(fs->e2fs_gd[c].ext2bgd_i_bitmap),
				fs->e2fs_bsize);
		} else {
			getblk(ino_bitmap, fs2h32(fs->e2fs_gd[c].ext2bgd_i_bitmap),
				fs->e2fs_bsize);
		}
		memset(bbmap, 0, fs->e2fs_bsize);
		memset(ibmap, 0, fs->e2fs_bsize);
		memset(&idesc[0], 0, sizeof idesc);
		for (i = 0; i < 3; i++) {
			idesc[i].id_type = ADDR;
		}

		j = fs->e2fs.e2fs_ipg * c + 1;

		for (i = 0; i < fs->e2fs.e2fs_ipg; j++, i++) {
			if ((j < EXT2_FIRSTINO) && (j != EXT2_ROOTINO)) {
				setbit(ibmap, i);
				nifree--;
				continue;
			}
			if (j > fs->e2fs.e2fs_icount) {
				setbit(ibmap, i);
				continue;
			}
			switch (statemap[j]) {

			case USTATE:
				break;

			case DSTATE:
			case DCLEAR:
			case DFOUND:
				ndirs++;
				/* fall through */

			case FSTATE:
			case FCLEAR:
				nifree--;
				setbit(ibmap, i);
				break;

			default:
				errexit("BAD STATE %d FOR INODE I=%ld\n",
				    statemap[j], j);
			}
		}

		/* fill in unused par of the inode map */
		for (i = fs->e2fs.e2fs_ipg / NBBY; i < fs->e2fs_bsize; i++)
			ibmap[i] = 0xff;

		dbase = c * sblock.e2fs.e2fs_bpg +
		    sblock.e2fs.e2fs_first_dblock;
		dmax = (c+1) * sblock.e2fs.e2fs_bpg +
		    sblock.e2fs.e2fs_first_dblock;

		for (i = 0, d = dbase;
		     d < dmax;
		     d ++, i ++) {
			if (testbmap(d) || d >= sblock.e2fs.e2fs_bcount) {
				setbit(bbmap, i);
				continue;
			} else {
				nbfree++;
			}

		}
		cs_nbfree += nbfree;
		cs_nifree += nifree;
		cs_ndir += ndirs;

		if (debug && (fs2h16(fs->e2fs_gd[c].ext2bgd_nbfree) != nbfree ||
		    fs2h16(fs->e2fs_gd[c].ext2bgd_nifree) != nifree ||
		    fs2h16(fs->e2fs_gd[c].ext2bgd_ndirs) != ndirs)) {
			printf("summary info for cg %d is %d, %d, %d,"
					"should be %d, %d, %d\n", c,
					fs2h16(fs->e2fs_gd[c].ext2bgd_nbfree),
					fs2h16(fs->e2fs_gd[c].ext2bgd_nifree),
					fs2h16(fs->e2fs_gd[c].ext2bgd_ndirs),
					nbfree,
					nifree,
					ndirs);
		}
		(void)snprintf(msg, sizeof(msg),
		    "SUMMARY INFORMATIONS WRONG FOR CG #%d", c);
		if ((fs2h16(fs->e2fs_gd[c].ext2bgd_nbfree) != nbfree ||
			fs2h16(fs->e2fs_gd[c].ext2bgd_nifree) != nifree ||
			fs2h16(fs->e2fs_gd[c].ext2bgd_ndirs) != ndirs) &&
			dofix(&idesc[0], msg)) {
			fs->e2fs_gd[c].ext2bgd_nbfree = h2fs16(nbfree);
			fs->e2fs_gd[c].ext2bgd_nifree = h2fs16(nifree);
			fs->e2fs_gd[c].ext2bgd_ndirs = h2fs16(ndirs);
			sbdirty();
		}

		if (debug && memcmp(blk_bitmap->b_un.b_buf, bbmap, fs->e2fs_bsize)) {
			printf("blk_bitmap:\n");
			print_bmap(blk_bitmap->b_un.b_buf, fs->e2fs_bsize);
			printf("bbmap:\n");
			print_bmap(bbmap, fs->e2fs_bsize);
		}

		(void)snprintf(msg, sizeof(msg),
		    "BLK(S) MISSING IN BIT MAPS #%d", c);
		if (memcmp(blk_bitmap->b_un.b_buf, bbmap, fs->e2fs_bsize) &&
			dofix(&idesc[1], msg)) {
			memcpy(blk_bitmap->b_un.b_buf, bbmap, fs->e2fs_bsize);
			dirty(blk_bitmap);
		}
		if (debug && memcmp(ino_bitmap->b_un.b_buf, ibmap, fs->e2fs_bsize)) {
			printf("ino_bitmap:\n");
			print_bmap(ino_bitmap->b_un.b_buf, fs->e2fs_bsize);
			printf("ibmap:\n");
			print_bmap(ibmap, fs->e2fs_bsize);
		}
		(void)snprintf(msg, sizeof(msg),
		    "INODE(S) MISSING IN BIT MAPS #%d", c);
		if (memcmp(ino_bitmap->b_un.b_buf, ibmap, fs->e2fs_bsize) &&
			dofix(&idesc[1], msg)) {
			memcpy(ino_bitmap->b_un.b_buf, ibmap, fs->e2fs_bsize);
			dirty(ino_bitmap);
		}

	}
	if (debug && (fs->e2fs.e2fs_fbcount != cs_nbfree ||
		fs->e2fs.e2fs_ficount != cs_nifree)) {
		printf("summary info bad in superblock: %d, %d should be %d, %d\n",
		fs->e2fs.e2fs_fbcount, fs->e2fs.e2fs_ficount,
		cs_nbfree, cs_nifree);
	}
	if ((fs->e2fs.e2fs_fbcount != cs_nbfree ||
		fs->e2fs.e2fs_ficount != cs_nifree)
	    && dofix(&idesc[0], "SUPERBLK SUMMARY INFORMATION BAD")) {
		fs->e2fs.e2fs_fbcount = cs_nbfree;
		fs->e2fs.e2fs_ficount = cs_nifree;
		sbdirty();
	}
	free(ibmap);
	free(bbmap);
}