static uint log_balloc(uint dev) { int b, bi, m, i; struct superblock sb; readsb(dev, &sb); for(b = 0; b < sb.size; b += BPB){ for(i = 0; i < b_index; i++) if(bp[i]->sector == BBLOCK(b, sb.ninodes)) { for(bi = 0; bi < BPB; bi++){ m = 1 << (bi % 8); if((bp[i]->data[bi/8] & m) == 0){ bp[i]->data[bi/8] |= m; return b + bi; } } } bp[b_index] = bread(dev, BBLOCK(b, sb.ninodes)); for(bi = 0; bi < BPB; bi++){ m = 1 << (bi % 8); if((bp[b_index]->data[bi/8] & m) == 0){ bp[b_index]->data[bi/8] |= m; b_index++; return b + bi; } } brelse(bp[b_index]); } panic("balloc: out of blocks"); }
// Allocate a zeroed disk block. static uint balloc(uint dev) { int b, bi, m; struct buf *bp; struct superblock sb; bp = 0; readsb(dev, &sb); for(b = 0; b < sb.size; b += BPB){ bp = bread(dev, BBLOCK(b, sb.ninodes)); for(bi = 0; bi < BPB && b + bi < sb.size; bi++){ m = 1 << (bi % 8); if((bp->data[bi/8] & m) == 0){ // Is block free? bp->data[bi/8] |= m; // Mark block in use. log_write(bp); brelse(bp); bzero(dev, b + bi); return b + bi; } } brelse(bp); } panic("balloc: out of blocks"); }
// Allocate a disk block. static uint balloc(uint dev) { int b, bi, m, bound; struct buf *bp; struct superblock sb; bp = 0; readsb(dev, &sb); for(b = 0; b < sb.size; b += BPB){ bp = bread(dev, BBLOCK(b, sb.ninodes)); if(b+BPB > sb.size){ //last bitmap block bound = sb.size % BPB; } else { bound = BPB; } for(bi = 0; bi < bound; bi++){ m = 1 << (bi % 8); if((bp->data[bi/8] & m) == 0){ // Is block free? bp->data[bi/8] |= m; // Mark block in use on disk. bwrite(bp); brelse(bp); return b + bi; } } brelse(bp); } //panic("balloc: out of blocks"); return 0; }
// Allocate a disk block. static uint balloc(uint dev) { int b, bi, m, bound; struct buf *bp; struct superblock sb; bp = 0; readsb(dev, &sb); // read superblock into sb for(b = 0; b < sb.size; b += BPB){ // loop through all available blocks // Return a B_BUSY buf with the contents of the indicated disk sector. bp = bread(dev, BBLOCK(b, sb.ninodes)); // get inode bitmap if(b+BPB > sb.size){ //last bitmap block bound = sb.size % BPB; } else { bound = BPB; } for(bi = 0; bi < bound; bi++){ // loop through all inode bitmap m = 1 << (bi % 8); if((bp->data[bi/8] & m) == 0){ // Is block free? bp->data[bi/8] |= m; // Mark block in use on disk. bwrite(bp); brelse(bp); return b + bi; } } brelse(bp); } //panic("balloc: out of blocks"); return 0; }
// Allocate a zeroed disk block. static uint balloc(uint dev, int partitionNumber) { int b, bi, m; struct buf* bp; struct superblock sb; // cprintf("balloc \n"); sb = sbs[partitionNumber]; bp = 0; for (b = 0; b < sb.size; b += BPB) { bp = bread(dev, BBLOCK(b, sb)); for (bi = 0; bi < BPB && b + bi < sb.size; bi++) { m = 1 << (bi % 8); if ((bp->data[bi / 8] & m) == 0) { // Is block free? bp->data[bi / 8] |= m; // Mark block in use. log_write(bp, partitionNumber); brelse(bp); bzero(dev, sb.offset + b + bi, partitionNumber); return b + bi; } } brelse(bp); } panic("balloc: out of blocks"); }
void markBlockInUse(uint bnum, uint inum) { if (bitmap[bnum] != 0 && bitmap[bnum] != inum) { ezErr("address used more than once."); } bitmap[bnum] = inum; unsigned char *bitBlock = blockPtrFromBNum(BBLOCK(bnum, ninodes)); if ( (bitBlock[bnum / 8] & (0x1 << (bnum % 8))) != (0x1 << (bnum % 8))) { ezErr("address used by inode but marked free in bitmap."); } }
// Allocate a disk block. static uint j_balloc(uint dev) { int b, bi, m, i; //struct buf *bp; struct superblock sb; // bp = 0; readsb(dev, &sb); for(b = 0; b < sb.size; b += BPB){ /* check in dirty blocks */ for(i = 0; i < b_index; i++) if(bp[i]->sector == BBLOCK(b, sb.ninodes)) { for(bi = 0; bi < BPB; bi++){ m = 1 << (bi % 8); if((bp[i]->data[bi/8] & m) == 0){ // Is block free? bp[i]->data[bi/8] |= m; // Mark block in use on disk. return b + bi; } } } /* load new block out of mem */ bp[b_index] = bread(dev, BBLOCK(b, sb.ninodes)); for(bi = 0; bi < BPB; bi++){ m = 1 << (bi % 8); if((bp[b_index]->data[bi/8] & m) == 0){ // Is block free? bp[b_index]->data[bi/8] |= m; // Mark block in use on disk. /* keep dirty around, move index to next*/ b_index++; return b + bi; } } // panic("eh"); brelse(bp[b_index]); } panic("balloc: out of blocks"); }
// Free a disk block. static void bfree(int dev, uint b) { struct buf *bp; int bi, m; readsb(dev, &sb); bp = bread(dev, BBLOCK(b, sb)); bi = b % BPB; m = 1 << (bi % 8); if((bp->data[bi/8] & m) == 0) panic("freeing free block"); bp->data[bi/8] &= ~m; log_write(bp); brelse(bp); }
// Free a disk block. static void bfree(int dev, uint b, int partitionNumber) { // cprintf("bfree \n"); struct buf* bp; int bi, m; struct superblock sb; sb = sbs[partitionNumber]; bp = bread(dev, BBLOCK(b, sb)); bi = b % BPB; m = 1 << (bi % 8); if ((bp->data[bi / 8] & m) == 0) panic("freeing free block"); bp->data[bi / 8] &= ~m; log_write(bp, partitionNumber); brelse(bp); }
// Free a disk block. static void bfree(int dev, uint b) { struct buf *bp; struct superblock sb; int bi, m; bzero(dev, b); readsb(dev, &sb); bp = bread(dev, BBLOCK(b, sb.ninodes)); bi = b % BPB; m = 1 << (bi % 8); if((bp->data[bi/8] & m) == 0) panic("freeing free block"); bp->data[bi/8] &= ~m; // Mark block free on disk. bwrite(bp); brelse(bp); }
int main(int argc, char *argv[]) { int fd = open(argv[1], O_RDONLY); if(fd <= -1){ fprintf(stderr, "image not found.\n"); //test return 1; } int rc; struct stat sbuf; rc = fstat(fd, &sbuf); assert(rc == 0); void *img_ptr = mmap(NULL, sbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); assert(img_ptr != MAP_FAILED); struct superblock *sb; sb = (struct superblock *)(img_ptr + BSIZE); if(DEBUG) printf("%d %d %d\n", sb->size, sb->nblocks, sb->ninodes);//TODO debug purposes only int range = (int)((sb->size) * BSIZE);//should be the max value of valid addresses //printf("%d\n", range); //inodes int i, p; struct dinode *dip = (struct dinode*)(img_ptr + (2*BSIZE)); int bitmap[sb->nblocks]; int inode_used[sb->nblocks]; int inode_marked[sb->ninodes]; int inode_referenced[sb->ninodes]; for(p = 0; p < sb->nblocks; p++){ inode_used[p] = 0; } for(p = 0; p < sb->ninodes; p++){ inode_marked[p] = 0; inode_referenced[p] = 0; } int inode_nlink[sb->ninodes]; int inode_num_refs[sb->ninodes]; for(p = 0; p < sb->ninodes; p++){ inode_nlink[p] = 0; inode_num_refs[p] = 0; } int dir_num_refs[sb->ninodes]; for(p = 0; p < sb->ninodes; p++) dir_num_refs[p] = 0; int block_addr, num; //char *entry_name; for(i = 0; i <= BBLOCK(sb->nblocks, sb->ninodes); i++) inode_used[i] = 1; for(i = 0; i< sb->ninodes; i++){ short type = dip->type; //CHECK:valid inodes //stat.h => type defs > T_DIR (directory) = 1 // T_FILE (file) = 2 // T_DEV (special device) = 3 //note: 0 => unallocated if(type == 0 || type == 1 || type == 2 || type == 3){ if(DEBUG) printf("%d type: %d\n", i, type);//TODO debug purposes only if(type == 2) inode_nlink[i] = dip->nlink; if(type != 0){ inode_marked[i] = 1; int dev = (dip->size)/BSIZE; int mod = (dip->size)%BSIZE; if(mod > 0){ dev++;//total number of blocks in use } if(dev > 12){ dev++;//acount for indirect block } if(DEBUG) printf("%d.%d\n", dev, mod);//can use this to get the total number of blocks in use if(DEBUG) printf("number of links = %d\nsize = %d\naddresses = ", dip->nlink, dip->size); int j; for(j = 0; j < (NDIRECT+1); j++){ block_addr = dip->addrs[j]; if(DEBUG) printf("%d ", dip->addrs[j]); //IMPORTANT: Switched the order of these! Allows us to pass another test if(dip->addrs[j] != 0){ if((dip->addrs[j]) < ((int)BBLOCK(sb->nblocks, sb->ninodes))+1 || (dip->addrs[j]) > range){//0 fprintf(stderr,"ERROR: bad address in inode.\n"); return 1; } } if(block_addr != 0){ if(inode_used[block_addr] == 1){ fprintf(stderr, "ERROR: address used more than once.\n"); //test return 1; } } inode_used[block_addr] = 1; //CHECK FOR CURRENT AND PARENT if(type == 1 && block_addr > 1 && j == 0){ //if directory if(check_curr_parent(img_ptr, block_addr)) return 1; } if(i == 1 && j == 0){ if(check_root_inum(img_ptr, block_addr)) return 1; } //check inode references and also see if parent directories are okay if(type == 1){ if(check_dirents(img_ptr, block_addr, i, inode_referenced, inode_num_refs, dir_num_refs, sb->ninodes)) return 1; } } if(DEBUG) printf("\n"); if(dev > NDIRECT){ if(DEBUG) printf("EXTRA BLOCK\n"); int *start_addr = (int*)(img_ptr + (block_addr*BSIZE)); for(j = 0; j < BSIZE/4; j++){ num = *(start_addr + j); if(num != 0){ if(DEBUG) printf("%d ", num); //IMPORTANT: Switched the order of these! Allows us to pass another test if(num < ((int)BBLOCK(sb->nblocks, sb->ninodes))+1 || num > range){//0 fprintf(stderr,"ERROR: bad address in inode.\n"); return 1; } if(inode_used[num] == 1){ fprintf(stderr, "ERROR: address used more than once.\n"); return 1; } inode_used[num] = 1; //check inode references and also see if parent directories are okay if(type == 1){ if(check_dirents(img_ptr, block_addr, i, inode_referenced, inode_num_refs, dir_num_refs, sb->ninodes)) return 1; } } } } if(DEBUG) printf("\n\n"); } dip++; }else{ fprintf(stderr,"ERROR: bad inode.\n"); return 1; } //CHECK:root directory if(i == ROOTINO && type != 1){ fprintf(stderr,"ERROR: root directory does not exist.\n"); return 1; } } int bitmap_block, j, n_block; uint *dbmp_addr; bitmap_block = BBLOCK(0, sb->ninodes); //printf("\n\nbitmap block: %d\n\n", bitmap_block); dbmp_addr = (uint*)(img_ptr + (bitmap_block*BSIZE)); uint word, bit, mask, word_mask; /* for(i = 0; i < (sb->nblocks)/32; i++){ word = *(dbmp_addr+i); word = word & (0x0000000F); printf("%d - %d data bitmap: %x\n", (i*32), ((i+1)*32)-1, word); //if(bit == 1){ //} } */ //dis the way I do the bitmap thing! You can replace it if you want, dylan. for(i = 0; i < ((sb->nblocks)/32+1); i++){ word = *(dbmp_addr+i); if(i < ((sb->nblocks)/32)){ for(j = 0; j < 32; j++){ n_block = (i*32)+(j); if(DEBUG) printf("%d ",n_block); mask = (0x1 << j); if(DEBUG) printf("mask: %x ",mask); if(DEBUG) printf("word: %x ",word); word_mask = word & mask; if(DEBUG) printf("masked word: %x ",word_mask); bit = word_mask >> j; if(DEBUG) printf("data bitmap: %x\n", bit); if(bit == 1) bitmap[n_block] = 1; else bitmap[n_block] = 0; } } else { for(j = 0; j < (sb->nblocks % 32); j++){ n_block = (i*32)+(j); if(DEBUG) printf("%d ",n_block); mask = (0x1 << j); if(DEBUG) printf("mask: %x ",mask); word = *(dbmp_addr+i); if(DEBUG) printf("word: %x ",word); word = word & mask; if(DEBUG) printf("masked word: %x ",word); bit = word >> j; if(DEBUG) printf("data bitmap: %x\n", bit); if(bit == 1) bitmap[n_block] = 1; else bitmap[n_block] = 0; } } }