Ejemplo n.º 1
0
void mkentry(uint16_t inum)
{
    struct dinode rootino;
    struct direct dentry;
    uint16_t d;

    iread(ROOTINODE, &rootino);
    for (d = 0; d < swizzle32(rootino.i_size)/32; ++d) {
        dirread(&rootino, d, &dentry);
        if (dentry.d_ino == 0 && dentry.d_name[0] == '\0') {
            dentry.d_ino = swizzle16(inum);
            sprintf(dentry.d_name, "l+f%d", inum);
            dirwrite(&rootino, d, &dentry);
            return;
        }
    }
    printf("Sorry... No empty slots in root directory.\n");
}
Ejemplo n.º 2
0
void pass5(void)
{
    uint16_t n;
    struct dinode ino;
    int yes();

    for (n = ROOTINODE; n < 8 * (swizzle16(superblock.s_isize) - 2); ++n) {
        iread(n, &ino);

        if (ino.i_mode == 0) {
            if (linkmap[n] != -1)
                panic("Inconsistent linkmap");
            continue;
        }

        if (linkmap[n] == -1 && ino.i_mode != 0)
            panic("Inconsistent linkmap");

        if (linkmap[n] > 0 && swizzle16(ino.i_nlink) != linkmap[n]) {
            printf("Inode %d has link count %d should be %d. Fix? ",
                    n, swizzle16(ino.i_nlink), linkmap[n]);
            if (yes()) {
                ino.i_nlink = swizzle16(linkmap[n]);
                iwrite(n, &ino);
            }
        }

        if (linkmap[n] == 0) {
            if ((swizzle16(ino.i_mode) & F_MASK) == F_BDEV ||
                    (swizzle16(ino.i_mode) & F_MASK) == F_CDEV ||
                    (ino.i_size == 0)) {
                printf("Useless inode %d with mode 0%o has become detached. Link count is %d. Zap? ",
                        n, swizzle16(ino.i_mode), swizzle16(ino.i_nlink));
                if (yes()) {
                    ino.i_nlink = 0;
                    ino.i_mode = 0;
                    iwrite(n, &ino);
                    superblock.s_tinode =
                                swizzle16(swizzle16(superblock.s_tinode) + 1);
                    dwrite((blkno_t) 1, (char *) &superblock);
                }
            } else {
#if 0
                printf("Inode %d has become detached. Link count is %d. Fix? ",
                        n, swizzle16(ino.i_nlink));
                if (yes()) {
                    ino.i_nlink = 1;
                    iwrite(n, &ino);
                    mkentry(n);
                }
#else
                printf("Inode %d has become detached. Link count is %d. ",
                        n, swizzle16(ino.i_nlink));
                if (ino.i_nlink == 0)
                    printf("Zap? ");
                else
                    printf("Fix? ");
                if (yes()) {
                    if (ino.i_nlink == 0) {
                        ino.i_nlink = 0;
                        ino.i_mode = 0;
                        iwrite(n, &ino);
                        superblock.s_tinode =
                                swizzle16(swizzle16(superblock.s_tinode) + 1);
                        dwrite((blkno_t) 1, (char *) &superblock);
                    } else {
                        ino.i_nlink = swizzle16(1);
                        iwrite(n, &ino);
                        mkentry(n);
                    }
                }
#endif
            }
        }

    }
}
Ejemplo n.º 3
0
void ckdir(uint16_t inum, uint16_t pnum, char *name)
{
    struct dinode ino;
    struct direct dentry;
    uint16_t j;
    int c;
    int nentries;
    char ename[150];

    iread(inum, &ino);
    if ((swizzle16(ino.i_mode) & F_MASK) != F_DIR)
        return;
    ++depth;

    if (swizzle32(ino.i_size) % 32 != 0) {
        printf("Directory inode %d has improper length. Fix? ", inum);
        if (yes()) {
            ino.i_size = swizzle32(swizzle32(ino.i_size) & ~0x1f);
            iwrite(inum, &ino);
        }
    }
    nentries = swizzle32(ino.i_size)/32;

    for (j = 0; j < nentries; ++j) {
        dirread(&ino, j, &dentry);

#if 1 /**HP**/
        {
            int i;

            for (i = 0; i < 30; ++i) if (dentry.d_name[i] == '\0') break;
            for (     ; i < 30; ++i) dentry.d_name[i] = '\0';
            dirwrite(&ino, j, &dentry);
        }
#endif

        if (dentry.d_ino == 0)
            continue;

        if (swizzle16(dentry.d_ino) < ROOTINODE ||
                swizzle16(dentry.d_ino) >= 8 * swizzle16(superblock.s_isize)) {
            printf("Directory entry %s%-1.14s has out-of-range inode %u. Zap? ",
                    name, dentry.d_name, swizzle16(dentry.d_ino));
            if (yes()) {
                dentry.d_ino = 0;
                dentry.d_name[0] = '\0';
                dirwrite(&ino, j, &dentry);
                continue;
            }
        }
        if (dentry.d_ino && linkmap[swizzle16(dentry.d_ino)] == -1) {
            printf("Directory entry %s%-1.14s points to bogus inode %u. Zap? ",
                    name, dentry.d_name, swizzle16(dentry.d_ino));
            if (yes()) {
                dentry.d_ino = 0;
                dentry.d_name[0] = '\0';
                dirwrite(&ino, j, &dentry);
                continue;
            }
        }
        ++linkmap[swizzle16(dentry.d_ino)];

        for (c = 0; c < 30 && dentry.d_name[c]; ++c) {
            if (dentry.d_name[c] == '/') {
                printf("Directory entry %s%-1.30s contains slash. Fix? ",
                        name, dentry.d_name);
                if (yes()) {
                    dentry.d_name[c] = 'X';
                    dirwrite(&ino, j, &dentry);
                }
            }
        }

        if (strncmp(dentry.d_name, ".", 30) == 0 && swizzle16(dentry.d_ino) != inum) {
            printf("Dot entry %s%-1.30s points to wrong place. Fix? ",
                    name, dentry.d_name);
            if (yes()) {
                dentry.d_ino = swizzle16(inum);
                dirwrite(&ino, j, &dentry);
            }
        }
        if (strncmp(dentry.d_name, "..", 30) == 0 && swizzle16(dentry.d_ino) != pnum) {
            printf("DotDot entry %s%-1.30s points to wrong place. Fix? ",
                    name, dentry.d_name);
            if (yes()) {
                dentry.d_ino = swizzle16(pnum);
                dirwrite(&ino, j, &dentry);
            }
        }
        if (swizzle16(dentry.d_ino) != pnum &&
                swizzle16(dentry.d_ino) != inum && depth < MAXDEPTH) {
            strcpy(ename, name);
            strcat(ename, dentry.d_name);
            strcat(ename, "/");
            ckdir(swizzle16(dentry.d_ino), inum, ename);
        }
    }
    --depth;
}
Ejemplo n.º 4
0
int main(int argc, char **argv)
{
    char *buf;
    char *op;

    if(argc != 2){
        fprintf(stderr, "syntax: fsck [devfile][:offset]\n");
        return 1;
    }
    
    op = strchr(argv[1], ':');
    if (op) {
        *op++ = 0;
        offset = atol(op);
    }

    if(fd_open(argv[1])){
        printf("Cannot open file\n");
        return -1;
    }

    buf = daread(1);
    bcopy(buf, (char *) &superblock, sizeof(struct filesys));

    /* Verify the fsize and isize parameters */
    if (superblock.s_mounted == SMOUNTED_WRONGENDIAN) {
        swizzling = 1;
        printf("Checking file system with reversed byte order.\n");
    }

    if (swizzle16(superblock.s_mounted) != SMOUNTED) {
        printf("Device %d has invalid magic number %d. Fix? ", dev, superblock.s_mounted);
        if (!yes())
            exit(-1);
        superblock.s_mounted = swizzle16(SMOUNTED);
        dwrite((blkno_t) 1, (char *) &superblock);
    }
    printf("Device %d has fsize = %d and isize = %d. Continue? ",
            dev, swizzle16(superblock.s_fsize), swizzle16(superblock.s_isize));
    if (!yes())
        exit(-1);

    bitmap = calloc(swizzle16(superblock.s_fsize), sizeof(char));
    linkmap = (int16_t *) calloc(8 * swizzle16(superblock.s_isize), sizeof(int16_t));

    if (!bitmap || !linkmap) {
        fprintf(stderr, "Not enough memory.\n");
        exit(-1);
    }

    printf("Pass 1: Checking inodes...\n");
    pass1();

    printf("Pass 2: Rebuilding free list...\n");
    pass2();

    printf("Pass 3: Checking block allocation...\n");
    pass3();

    printf("Pass 4: Checking directory entries...\n");
    pass4();

    printf("Pass 5: Checking link counts...\n");
    pass5();

    printf("Done.\n");

    exit(0);
}
Ejemplo n.º 5
0
void pass3(void)
{
    uint16_t n;
    struct dinode ino;
    uint16_t mode;
    blkno_t b;
    blkno_t bno;
    blkno_t newno;
    blkno_t blk_alloc0();
    /*--- was blk_alloc ---*/
    blkno_t getblkno();
    int yes();

    for (b = swizzle16(superblock.s_isize); b < swizzle16(superblock.s_fsize); ++b)
        bitmap[b] = 0;

    for (n = ROOTINODE; n < 8 * (swizzle16(superblock.s_isize) - 2); ++n) {
        iread(n, &ino);

        mode = swizzle16(ino.i_mode) & F_MASK;
        if (mode != F_REG && mode != F_DIR)
            continue;

        /* Check singly indirect blocks */

        for (b = 18; b < 20; ++b) {
            if (ino.i_addr[b] != 0) {
                if (bitmap[swizzle16(ino.i_addr[b])] != 0) {
                    printf("Indirect block %d in inode %u value %u multiply allocated. Fix? ",
                            b, n, swizzle16(ino.i_addr[b]));
                    if (yes()) {
                        newno = blk_alloc0(&superblock);
                        if (newno == 0)
                            printf("Sorry... No more free blocks.\n");
                        else {
                            dwrite(newno, daread(swizzle16(ino.i_addr[b])));
                            ino.i_addr[b] = swizzle16(newno);
                            iwrite(n, &ino);
                        }
                    }
                } else
                    bitmap[swizzle16(ino.i_addr[b])] = 1;
            }
        }

        /* Check the rest */
        for (bno = 0; bno <= swizzle32(ino.i_size)/512; ++bno) {
            b = getblkno(&ino, bno);

            if (b != 0) {
                if (bitmap[b] != 0) {
                    printf("Block %d in inode %u value %u multiply allocated. Fix? ",
                            bno, n, b);
                    if (yes()) {
                        newno = blk_alloc0(&superblock);
                        if (newno == 0)
                            printf("Sorry... No more free blocks.\n");
                        else {
                            dwrite(newno, daread(b));
                            setblkno(&ino, bno, newno);
                            iwrite(n, &ino);
                        }
                    }
                } else
                    bitmap[b] = 1;
            }
        }

    }

}
Ejemplo n.º 6
0
void pass2(void)
{
    blkno_t j;
    blkno_t oldtfree;
    int s;
    int yes();

    printf("Rebuild free list? ");
    if (!yes())
        return;

    oldtfree = swizzle16(superblock.s_tfree);

    /* Initialize the superblock-block */

    superblock.s_ninode = 0;
    superblock.s_nfree = swizzle16(1);
    superblock.s_free[0] = 0;
    superblock.s_tfree = 0;

    /* Free each block, building the free list */

    for (j = swizzle16(superblock.s_fsize) - 1; j >= swizzle16(superblock.s_isize); --j) {
        if (bitmap[j] == 0) {
            if (swizzle16(superblock.s_nfree) == 50) {
                dwrite(j, (char *) &superblock.s_nfree);
                superblock.s_nfree = 0;
            }
            superblock.s_tfree = swizzle16(swizzle16(superblock.s_tfree)+1);
            s = swizzle16(superblock.s_nfree);
            superblock.s_free[s++] = swizzle16(j);
            superblock.s_nfree = swizzle16(s);
        }
    }

    dwrite((blkno_t) 1, (char *) &superblock);

    if (oldtfree != swizzle16(superblock.s_tfree))
        printf("During free list regeneration s_tfree was changed to %d from %d.\n",
                swizzle16(superblock.s_tfree), oldtfree);

}
Ejemplo n.º 7
0
void pass1(void)
{
    uint16_t n;
    struct dinode ino;
    uint16_t mode;
    blkno_t b;
    blkno_t bno;
    uint16_t icount;
    blkno_t *buf;

    blkno_t getblkno();
    int yes();			/* 1.4.98 - HFB */

    icount = 0;

    for (n = ROOTINODE; n < 8 * (swizzle16(superblock.s_isize) - 2); ++n) {
        iread(n, &ino);
        linkmap[n] = -1;
        if (ino.i_mode == 0)
            continue;

        mode = swizzle16(ino.i_mode) & F_MASK;
        /* FIXME: named pipes.. */

        /* Check mode */
        if (mode != F_REG && mode != F_DIR && mode != F_BDEV && mode != F_CDEV) {
            printf("Inode %d with mode 0%o is not of correct type. Zap? ",
                    n, swizzle16(ino.i_mode));
            if (yes()) {
                ino.i_mode = 0;
                ino.i_nlink = 0;
                iwrite(n, &ino);
                continue;
            }
        }
        linkmap[n] = 0;
        ++icount;
        /* Check size */

        if (swizzle32(ino.i_size) < 0) {
            printf("Inode %d offset is negative with value of %ld. Fix? ",
                    n, (long)swizzle32(ino.i_size));
            if (yes()) {
                ino.i_size = 0;
                iwrite(n, &ino);
            }
        }
        /* Check blocks and build free block map */
        if (mode == F_REG || mode == F_DIR) {
            /* Check singly indirect blocks */

            for (b = 18; b < 20; ++b) {
                if (ino.i_addr[b] != 0 && 
                    (swizzle16(ino.i_addr[b]) < swizzle16(superblock.s_isize) ||
                            swizzle16(ino.i_addr[b]) >= swizzle16(superblock.s_fsize))) {
                    printf("Inode %d singly ind. blk %d out of range, val = %u. Zap? ",
                            n, b, swizzle16(ino.i_addr[b]));
                    if (yes()) {
                        ino.i_addr[b] = 0;
                        iwrite(n, &ino);
                    }
                }
                if (ino.i_addr[b] != 0 && swizzle32(ino.i_size) < 18*512) {
                    printf("Inode %d singly ind. blk %d past end of file, val = %u. Zap? ",
                            n, b, swizzle16(ino.i_addr[b]));
                    if (yes()) {
                        ino.i_addr[b] = 0;
                        iwrite(n, &ino);
                    }
                }
                if (ino.i_addr[b] != 0)
                    bitmap[swizzle16(ino.i_addr[b])] = 1;
            }

            /* Check the double indirect blocks */
            if (ino.i_addr[19] != 0) {
                buf = (blkno_t *) daread(swizzle16(ino.i_addr[19]));
                for (b = 0; b < 256; ++b) {
                    if (buf[b] != 0 && (swizzle16(buf[b]) < swizzle16(superblock.s_isize) ||
                                swizzle16(buf[b]) >= swizzle16(superblock.s_fsize))) {
                        printf("Inode %d doubly ind. blk %d is ", n, b);
                        printf("out of range, val = %u. Zap? ", swizzle16(buf[b]));
                        /* 1.4.98 - line split.  HFB */
                        if (yes()) {
                            buf[b] = 0;
                            dwrite(b, (char *) buf);
                        }
                    }
                    if (buf[b] != 0)
                        bitmap[swizzle16(buf[b])] = 1;
                }
            }
            /* Check the rest */
            for (bno = 0; bno <= swizzle32(ino.i_size)/512; ++bno) {
                b = getblkno(&ino, bno);

                if (b != 0 && (b < swizzle16(superblock.s_isize) || b >= swizzle16(superblock.s_fsize))) {
                    printf("Inode %d block %d out of range, val = %u. Zap? ",
                            n, bno, b);
                    if (yes()) {
                        setblkno(&ino, bno, 0);
                        iwrite(n, &ino);
                    }
                }
                if (b != 0)
                    bitmap[b] = 1;
            }
        }
    }
    /* Fix free inode count in superblock block */
    if (swizzle16(superblock.s_tinode) != 8 * (swizzle16(superblock.s_isize) - 2) - ROOTINODE - icount) {
        printf("Free inode count in superblock block is %u, should be %u. Fix? ",
                swizzle16(superblock.s_tinode), 8 * (swizzle16(superblock.s_isize) - 2) - ROOTINODE - icount);

        if (yes()) {
            superblock.s_tinode = 8 * (swizzle16(superblock.s_isize) - 2) - ROOTINODE - icount;
            dwrite((blkno_t) 1, (char *) &superblock);
        }
    }
}
Ejemplo n.º 8
0
int main(int argc, char **argv)
{
	uint16_t fsize, isize, bsize = 512, shift = 0;
	uint16_t j;
	uint32_t s;
	int opt;

	while((opt = getopt(argc, argv, "Xb:")) != -1) {
		switch(opt) {
			case 'X':	
				swizzling = 1;
				break;
			case 'b':
				bsize = atoi(optarg);
				shift = validate(bsize);
				break;
			default:
				usage();
		}
	}
	if (argc - optind != 3)
		usage();

	if (sizeof(inode) != 512) {
		printf("inode is the wrong size -- %d\n",
		       (int) sizeof(inode));
	}

	isize = (uint16_t) atoi(argv[optind + 1]);
	fsize = (uint16_t) atoi(argv[optind + 2]);

	if (fsize < 3 || isize < 2 || isize >= fsize) {
		printf("Bad parameter values\n");
		return -1;
	}

	memset(zero512, 0, 512);

	printf("Making %d byte/block filesystem with %s byte order on device %s with fsize = %u and isize = %u.\n",
	       bsize, swizzling==0 ? "normal" : "reversed", argv[optind], fsize, isize);

	if (fd_open(argv[optind])) {
		printf("Can't open device");
		return -1;
	}

	s = fsize << shift;

	/* Zero out the blocks */
	for (j = 0; j < s; ++j)
		dwrite(j, zero512);

	/* Initialize the super-block */

	fs_super.fs.s_mounted = swizzle16(SMOUNTED);	/* Magic number */
	fs_super.fs.s_isize = swizzle16(isize);
	fs_super.fs.s_fsize = swizzle16(fsize);
	fs_super.fs.s_nfree = swizzle16(1);
	fs_super.fs.s_free[0] = 0;
	fs_super.fs.s_tfree = 0;
	fs_super.fs.s_ninode = 0;
	fs_super.fs.s_tinode = swizzle16(8 * (isize - 2) - 2);
	fs_super.fs.s_shift = shift;

	/* Free each block, building the free list. This is done in
	   terms of the block shift, while isize is in 512 byte blocks.
	   Adjust isize so that it's in block terms and references the
	   block after the last inode */
	  
	isize <<= shift;

	/* Don't free the block isize because it's got the / directory in it */
	for (j = fsize - 1; j > isize; --j) {
		int n;
		if (swizzle16(fs_super.fs.s_nfree) == 50) {
			dwrite(j, (char *) &fs_super.fs.s_nfree);
			fs_super.fs.s_nfree = 0;
		}

		fs_super.fs.s_tfree =
		    swizzle16(swizzle16(fs_super.fs.s_tfree) + 1);
		n = swizzle16(fs_super.fs.s_nfree);
		fs_super.fs.s_free[n++] = swizzle16(j);
		fs_super.fs.s_nfree = swizzle16(n);
	}

	/* The inodes are already zeroed out */
	/* create the root dir */
	inode[ROOTINODE].i_mode = swizzle16(F_DIR | (0777 & MODE_MASK));
	inode[ROOTINODE].i_nlink = swizzle16(3);
	inode[ROOTINODE].i_size = swizzle32(64);
	inode[ROOTINODE].i_addr[0] = swizzle16(isize);

	/* Reserve reserved inode */
	inode[0].i_nlink = swizzle16(1);
	inode[0].i_mode = ~0;

	dwrite(2, (char *) inode);

	dirbuf[0].d_ino = swizzle16(dirbuf[0].d_ino);
	dirbuf[1].d_ino = swizzle16(dirbuf[1].d_ino);
	dwrite(isize, (char *) dirbuf);

	/* Write out super block */
	dwrite(1, (char *) &fs_super);
	return 0;
}
Ejemplo n.º 9
0
void mkfs(uint16_t fsize, uint16_t isize)
{
	uint16_t j;

	/* Zero out the blocks */

	for (j = 0; j < fsize; ++j)
		dwrite(j, zero512);

	/* Initialize the super-block */

	fs_super.s_mounted = swizzle16(SMOUNTED);	/* Magic number */
	fs_super.s_isize = swizzle16(isize);
	fs_super.s_fsize = swizzle16(fsize);
	fs_super.s_nfree = swizzle16(1);
	fs_super.s_free[0] = 0;
	fs_super.s_tfree = 0;
	fs_super.s_ninode = 0;
	fs_super.s_tinode = swizzle16(8 * (isize - 2) - 2);

	/* Free each block, building the free list */
	for (j = fsize - 1; j >= isize + 1; --j) {
		int n;
		if (swizzle16(fs_super.s_nfree) == 50) {
			dwrite(j, (char *) &fs_super.s_nfree);
			fs_super.s_nfree = 0;
		}

		fs_super.s_tfree =
		    swizzle16(swizzle16(fs_super.s_tfree) + 1);
		n = swizzle16(fs_super.s_nfree);
		fs_super.s_free[n++] = swizzle16(j);
		fs_super.s_nfree = swizzle16(n);
	}

	/* The inodes are already zeroed out */
	/* create the root dir */
	inode[ROOTINODE].i_mode = swizzle16(F_DIR | (0777 & MODE_MASK));
	inode[ROOTINODE].i_nlink = swizzle16(3);
	inode[ROOTINODE].i_size = swizzle32(64);
	inode[ROOTINODE].i_addr[0] = swizzle16(isize);

	/* Reserve reserved inode */
	inode[0].i_nlink = swizzle16(1);
	inode[0].i_mode = ~0;

	dwrite(2, (char *) inode);

	dirbuf[0].d_ino = swizzle16(dirbuf[0].d_ino);
	dirbuf[1].d_ino = swizzle16(dirbuf[1].d_ino);
	dwrite(isize, (char *) dirbuf);

	/* Write out super block */
	dwrite(1, (char *) &fs_super);
}