BOOL flush1(struct buffer FAR * bp) { /* All lines with changes on 9/4/00 by BER marked below */ UWORD result; /* BER 9/4/00 */ if ((bp->b_flag & BFR_VALID) && (bp->b_flag & BFR_DIRTY)) { result = dskxfer(bp->b_unit, getblkno(bp), (VOID FAR *) bp->b_buffer, 1, DSKWRITE); /* BER 9/4/00 */ if (bp->b_flag & BFR_FAT) { int i = bp->b_copies; ULONG blkno = getblkno(bp); while (--i > 0) { blkno += bp->b_offset; result = dskxfer(bp->b_unit, blkno, (VOID FAR *) bp->b_buffer, 1, DSKWRITE); /* BER 9/4/00 */ } } } else result = 0; /* This negates any error code returned in result...BER */ /* and 0 returned, if no errors occurred - tom */ bp->b_flag &= ~BFR_DIRTY; /* even if error, mark not dirty */ if (result != 0) /* otherwise system has trouble */ bp->b_flag &= ~BFR_VALID; /* continuing. */ return (TRUE); /* Forced to TRUE...was like this before dskxfer() */ /* returned error codes...BER */ }
BOOL DeleteBlockInBufferCache(ULONG blknolow, ULONG blknohigh, COUNT dsk) { struct buffer FAR *bp; /* Search through buffers to see if the required block */ /* is already in a buffer */ for (bp = firstbuf; bp != NULL; bp = bp->b_next) { if (blknolow <= getblkno(bp) && getblkno(bp) <= blknohigh && (bp->b_flag & BFR_VALID) && (bp->b_unit == dsk)) { flush1(bp); } } return FALSE; }
void dumpBufferCache(void) { struct buffer FAR *bp; int printed = 0; /* Search through buffers to see if the required block */ /* is already in a buffer */ for (bp = firstbuf; bp != NULL;bp = bp->b_next) { printf("%8lx %02x ",getblkno(bp),bp->b_flag); if (++printed % 6 == 0) printf("\n"); } printf("\n"); }
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); } } }
BOOL searchblock(ULONG blkno, COUNT dsk, struct buffer FAR ** pBuffp) { int fat_count = 0; struct buffer FAR *bp; struct buffer FAR *lbp = NULL; struct buffer FAR *lastNonFat = NULL; struct buffer FAR *uncacheBuf = NULL; #ifdef DISPLAY_GETBLOCK printf("[searchblock %d, blk %ld, buf ", dsk, blkno); #endif /* Search through buffers to see if the required block */ /* is already in a buffer */ for (bp = firstbuf; bp != NULL;lbp = bp, bp = bp->b_next) { if ((getblkno(bp) == blkno) && (bp->b_flag & BFR_VALID) && (bp->b_unit == dsk)) { /* found it -- rearrange LRU links */ if (lbp != NULL) { lbp->b_next = bp->b_next; bp->b_next = firstbuf; firstbuf = bp; } #ifdef DISPLAY_GETBLOCK printf("HIT %04x:%04x]\n", FP_SEG(bp), FP_OFF(bp)); #endif *pBuffp = bp; return TRUE; } if (bp->b_flag & BFR_UNCACHE) uncacheBuf = bp; if (bp->b_flag & BFR_FAT) fat_count++; else lastNonFat = bp; } /* now take either the last buffer in chain (not used recently) or, if we are low on FAT buffers, the last non FAT buffer */ if (uncacheBuf) { lbp = uncacheBuf; } else { if (lbp ->b_flag & BFR_FAT && fat_count < 3 && lastNonFat) { lbp = lastNonFat; } } lbp->b_flag &= ~BFR_UNCACHE; /* reset uncache attribute */ *pBuffp = lbp; #ifdef DISPLAY_GETBLOCK printf("MISS, replace %04x:%04x]\n", FP_SEG(lbp), FP_OFF(lbp)); #endif if (lbp != firstbuf) /* move to front */ { for (bp = firstbuf; bp->b_next != lbp; bp = bp->b_next) ; bp->b_next = bp->b_next->b_next; lbp->b_next = firstbuf; firstbuf = lbp; } return FALSE; }