/* exactly the same as getblock(), but the data will be completely overwritten. so there is no need to read from disk first */ struct buffer FAR * getblockOver(ULONG blkno, COUNT dsk) { struct buffer FAR *bp; /* Search through buffers to see if the required block */ /* is already in a buffer */ if (searchblock(blkno, dsk, &bp)) { return bp; } /* The block we need is not in a buffer, we must make a buffer */ /* available. */ /* take the buffer than lbp points to and flush it, then make it available. */ if (flush1(bp)) /* success */ { bp->b_flag = 0; bp->b_unit = dsk; setblkno(bp, blkno); return bp; } else /* failure */ { return NULL; } }
struct buffer FAR *getblock(ULONG blkno, COUNT dsk) { struct buffer FAR *bp; /* Search through buffers to see if the required block */ /* is already in a buffer */ if (searchblock(blkno, dsk, &bp)) { return (bp); } /* The block we need is not in a buffer, we must make a buffer */ /* available, and fill it with the desired block */ /* take the buffer that lbp points to and flush it, then read new block. */ if (!flush1(bp)) return NULL; /* Fill the indicated disk buffer with the current track and sector */ if (dskxfer(dsk, blkno, (VOID FAR *) bp->b_buffer, 1, DSKREAD)) { return NULL; } bp->b_flag = BFR_VALID | BFR_DATA; bp->b_unit = dsk; setblkno(bp, blkno); return bp; }
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; } } } }
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); } } }