// Read and validate the file system bitmap. // // Read all the bitmap blocks into memory. // Set the "bitmap" pointer to point at the beginning of the first // bitmap block. // // Check that all reserved blocks -- 0, 1, and the bitmap blocks themselves -- // are all marked as in-use // (for each block i, assert(!block_is_free(i))). // // Hint: Assume that the superblock has already been loaded into // memory (in variable 'super'). Check out super->s_nblocks. void read_bitmap(void) { int r; uint32_t i, n; char *blk; // Read the bitmap into memory. // The bitmap consists of one or more blocks. A single bitmap block // contains the in-use bits for BLKBITSIZE blocks. There are // super->s_nblocks blocks in the disk altogether. // Set 'bitmap' to point to the first address in the bitmap. // Hint: Use read_block. // LAB 5: Your code here. n = super->s_nblocks / BLKBITSIZE; cprintf("read the nblocks: %d.\n", n); read_block(2, &blk); bitmap = (uint32_t *)blk; for (i = 1; i < n; i++) read_block(i + 2, NULL); // Make sure the reserved and root blocks are marked in-use. assert(!block_is_free(0)); assert(!block_is_free(1)); assert(bitmap); // Make sure that the bitmap blocks are marked in-use. // LAB 5: Your code here. for (i = 0; i < n; i++) assert(!block_is_free(i + 2)); cprintf("read_bitmap is good\n"); }
// Read and validate the file system bitmap. // // Read all the bitmap blocks into memory. // Set the "bitmap" pointer to point at the beginning of the first // bitmap block. // // Check that all reserved blocks -- 0, 1, and the bitmap blocks themselves -- // are all marked as in-use // (for each block i, assert(!block_is_free(i))). // // Hint: Assume that the superblock has already been loaded into // memory (in variable 'super'). Check out super->s_nblocks. void read_bitmap(void) { int r; uint32_t i; // Read the bitmap into memory. // The bitmap consists of one or more blocks. A single bitmap block // contains the in-use bits for BLKBITSIZE blocks. There are // super->s_nblocks blocks in the disk altogether. // Set 'bitmap' to point to the first address in the bitmap. // Hint: Use read_block. // LAB 5: Your code here. // bitmap blocks start at block 2. for (i = 0; i < (super->s_nblocks - 1) / BLKBITSIZE + 1; i++) { if ((r = read_block(i + 2, NULL)) < 0) panic("read_block for bitmap %d failed: %e.\n", i, r); } bitmap = (uint32_t *) diskaddr(2); // Make sure the reserved and root blocks are marked in-use. assert(!block_is_free(0)); assert(!block_is_free(1)); assert(bitmap); // Make sure that the bitmap blocks are marked in-use. // LAB 5: Your code here. for (i = 0; i < super->s_nblocks / BLKBITSIZE; i++) assert(!block_is_free(i + 2)); cprintf("read_bitmap is good\n"); }
/*merger two blocks, return left one (address order)*/ node_t * block_merge_left(node_t * b1, node_t * b2){ if ((b1!=AVAIL) && (block_is_free(b1))){ /* left adjacent block is free*/ block_remove(b1); /* remove from dll */ b1->size+=b2->size; /* size includes the header */ return b1; } else if((b1==AVAIL)||(!block_is_free(b1))){ return b2; } return b2; }
// Read and validate the file system bitmap. // // Read all the bitmap blocks into memory. // Set the "bitmap" pointer to point at the beginning of the first // bitmap block. // // Check that all reserved blocks -- 0, 1, and the bitmap blocks themselves -- // are all marked as in-use // (for each block i, assert(!block_is_free(i))). // // Hint: Assume that the superblock has already been loaded into // memory (in variable 'super'). Check out super->s_nblocks. void read_bitmap(void) { int error; uint32_t i; char *blk; // Read the bitmap into memory. // The bitmap consists of one or more blocks. A single bitmap block // contains the in-use bits for BLKBITSIZE blocks. There are // super->s_nblocks blocks in the disk altogether. // Set 'bitmap' to point to the first address in the bitmap. // Hint: Use read_block. // LAB 5: Your code here. // panic("read_bitmap not implemented"); int total = super->s_nblocks; int bitmapLastNo = BITMAPNO(total); // Read all the bitmap blocks into memory. // Set the "bitmap" pointer to point at the beginning of the first // bitmap block. error = read_block(BITMAP_START_BLOCK, &blk); if(error< 0) panic("bitmap load error"); // Set 'bitmap' to point to the first address in the bitmap. bitmap = (uint32_t *)blk; for(i=BITMAP_START_BLOCK; i<=bitmapLastNo; i++) { error = read_block(i, &blk); if(error< 0) panic("bitmap load error"); } // Check that all reserved blocks -- 0, 1, and the bitmap blocks themselves -- // are all marked as in-use // Make sure the reserved and root blocks are marked in-use. assert(!block_is_free(0)); assert(!block_is_free(1)); assert(bitmap); // Make sure that the bitmap blocks are marked in-use. // LAB 5: Your code here. for(i=BITMAP_START_BLOCK; i<=bitmapLastNo; i++) assert(!block_is_free(i)); cprintf("read_bitmap is good\n"); }
// Validate the file system bitmap. // // Check that all reserved blocks -- 0, 1, and the bitmap blocks themselves -- // are all marked as in-use. void check_bitmap(void) { uint32_t i; // Make sure all bitmap blocks are marked in-use for (i = 0; i * BLKBITSIZE < super->s_nblocks; i++) assert(!block_is_free(2+i)); // Make sure the reserved and root blocks are marked in-use. assert(!block_is_free(0)); assert(!block_is_free(1)); cprintf("bitmap is good\n"); }
// Make sure a particular disk block is loaded into memory. // Returns 0 on success, or a negative error code on error. // // If blk != 0, set *blk to the address of the block in memory. // // Hint: Use diskaddr, map_block, and ide_read. static int read_block(uint32_t blockno, char **blk) { int r; char *addr; if (super && blockno >= super->s_nblocks) panic("reading non-existent block %08x\n", blockno); if (bitmap && block_is_free(blockno)) panic("reading free block %08x\n", blockno); // LAB 5: Your code here. r = map_block(blockno); if (r) return r; addr = diskaddr(blockno); r = ide_read(blockno * BLKSECTS, addr, BLKSECTS); if (r) return r; if (blk) *blk = addr; return sys_page_map(0, addr, 0, addr, vpt[VPN(addr)] & PTE_USER); }
// Make sure a particular disk block is loaded into memory. // Returns 0 on success, or a negative error code on error. // // If blk != 0, set *blk to the address of the block in memory. // // Hint: Use diskaddr, map_block, and ide_read. static int read_block(uint32_t blockno, char **blk) { int r; char *addr; if (super && blockno >= super->s_nblocks) panic("reading non-existent block %08x\n", blockno); if (bitmap && block_is_free(blockno)) panic("reading free block %08x\n", blockno); // LAB 5: Your code here. addr = diskaddr(blockno); if (block_is_mapped(blockno)) { goto succeeded; } // now that the block is not in memory, allocate memory and read it in. if ((r = map_block(blockno)) < 0) return r; if ((r = ide_read(blockno * BLKSECTS, addr, BLKSECTS)) < 0) return r; succeeded: if (blk) *blk = addr; return 0; }
// Make sure a particular disk block is loaded into memory. // Returns 0 on success, or a negative error code on error. // // If blk != 0, set *blk to the address of the block in memory. // // Hint: Use diskaddr, map_block, and ide_read. static int read_block(uint32_t blockno, char **blk) { int r; char *addr; if (super && blockno >= super->s_nblocks) panic("reading non-existent block %08x\n", blockno); if (bitmap && block_is_free(blockno)) panic("reading free block %08x\n", blockno); addr = diskaddr(blockno); if(!block_is_mapped(blockno)){ if((r = map_block(blockno)) < 0) return r; r = ide_read(blockno*BLKSECTS, (void *)addr, BLKSECTS); if(r < 0) return r; } if(blk) *blk = addr; return 0; }
// Search the bitmap for a free block and allocate it. When you // allocate a block, immediately flush the changed bitmap block // to disk. // // Return block number allocated on success, // -E_NO_DISK if we are out of blocks. // // Hint: use free_block as an example for manipulating the bitmap. int alloc_block(void) { // The bitmap consists of one or more blocks. A single bitmap block // contains the in-use bits for BLKBITSIZE blocks. There are // super->s_nblocks blocks in the disk altogether. // LAB 5: Your code here. //panic("alloc_block not implemented"); uint32_t blockno; int flag; flag=0; for(blockno=0; blockno<super->s_nblocks; blockno++) { if(block_is_free(blockno)) { bitmap[blockno/32] ^= 1<<(blockno%32); flush_block(bitmap); flag=1; break; } } if(flag == 1) { return blockno; } else { return -E_NO_DISK; } }
// Fault any disk block that is read or written in to memory by // loading it from disk. // Hint: Use ide_read and BLKSECTS. static void bc_pgfault(struct UTrapframe *utf) { void *addr = (void *) utf->utf_fault_va; uint32_t blockno = ((uint32_t)addr - DISKMAP) / BLKSIZE; int r; // Check that the fault was within the block cache region if (addr < (void*)DISKMAP || addr >= (void*)(DISKMAP + DISKSIZE)) panic("page fault in FS: eip %08x, va %08x, err %04x", utf->utf_eip, addr, utf->utf_err); // Allocate a page in the disk map region and read the // contents of the block from the disk into that page. // // LAB 5: Your code here addr = ROUNDDOWN(addr, PGSIZE); if ((r = sys_page_alloc(0, addr, PTE_USER)) < 0) panic("sys_page_alloc: %e", r); if (ide_read(blockno * BLKSECTS, addr, BLKSECTS) < 0) panic("ide_read failed"); // Sanity check the block number. (exercise for the reader: // why do we do this *after* reading the block in?) if (super && blockno >= super->s_nblocks) panic("reading non-existent block %08x\n", blockno); // Check that the block we read was allocated. if (bitmap && block_is_free(blockno)) panic("reading free block %08x\n", blockno); }
// Make sure a particular disk block is loaded into memory. // Returns 0 on success, or a negative error code on error. // // If blk != 0, set *blk to the address of the block in memory. // // Hint: Use diskaddr, map_block, and ide_read. static int read_block(uint32_t blockno, char **blk) { int r; char *addr; if (super && blockno >= super->s_nblocks) panic("reading non-existent block %08x\n", blockno); if (bitmap && block_is_free(blockno)) panic("reading free block %08x\n", blockno); // LAB 5: Your code here. addr = diskaddr(blockno); if(!block_is_mapped(blockno)){ if ((r = sys_page_alloc(sys_getenvid(), diskaddr(blockno), PTE_U|PTE_P|PTE_W)) < 0) return r; if((r = ide_read(blockno*(BLKSIZE/SECTSIZE), addr, (size_t) BLKSIZE/SECTSIZE)) < 0) return r; } if(blk != 0) *blk = addr; return 0; }
// Make sure a particular disk block is loaded into memory. // Returns 0 on success, or a negative error code on error. // // If blk != 0, set *blk to the address of the block in memory. // // Hint: Use diskaddr, map_block, and ide_read. static int read_block(uint32_t blockno, char **blk) { int r; char *addr; if (super && blockno >= super->s_nblocks) panic("reading non-existent block %08x\n", blockno); if (bitmap && block_is_free(blockno)) panic("reading free block %08x\n", blockno); // LAB 5: Your code here. addr = diskaddr(blockno); int error = map_block(blockno); if(error<0) return error; int secno = blockno*BLKSECTS; error = ide_read(secno, addr, (size_t)BLKSECTS); if(error) return error; if(blk) *blk = addr; // panic("read_block not implemented"); return 0; }
// Fault any disk block that is read or written in to memory by // loading it from disk. // Hint: Use ide_read and BLKSECTS. static void bc_pgfault(struct UTrapframe *utf) { void *addr = (void *) utf->utf_fault_va; uint64_t blockno = ((uint64_t)addr - DISKMAP) / BLKSIZE; int r; // Check that the fault was within the block cache region if (addr < (void*)DISKMAP || addr >= (void*)(DISKMAP + DISKSIZE)) panic("page fault in FS: eip %08x, va %08x, err %04x", utf->utf_rip, addr, utf->utf_err); // Sanity check the block number. if (super && blockno >= super->s_nblocks) panic("reading non-existent block %08x\n", blockno); // Allocate a page in the disk map region, read the contents // of the block from the disk into that page, and mark the // page not-dirty (since reading the data from disk will mark // the page dirty). // // LAB 5: Your code here void *dst_addr = (void *) ROUNDDOWN(addr, BLKSIZE); r = sys_page_alloc(thisenv->env_id, dst_addr, PTE_U | PTE_P | PTE_W); // Project addition --> Transparent disk decryption (called only if disk block // is encrypted). Bitmap block has been left out of encryption, bitmap block data is tightly // bound in other routines, so can't encrypt. if(blockno == 2) ide_read(blockno * BLKSECTS, dst_addr, BLKSECTS); else if (blockno == 1) /* || (blockno == 2)) */ { if(!s_encrypted) ide_read(blockno * BLKSECTS, dst_addr, BLKSECTS); else { r = transparent_disk_decrypt(blockno, dst_addr); if(r) return; } } else { r = transparent_disk_decrypt(blockno, dst_addr); if(r) return; } // panic("bc_pgfault not implemented"); // Check that the block we read was allocated. (exercise for // the reader: why do we do this *after* reading the block // in?) if (bitmap && block_is_free(blockno)) panic("reading free block %08x\n", blockno); }
/*merger two blocks, return left one (address order)*/ node_t * block_merge_right(node_t * b1, node_t * b2){ if((b2!=NULL) &&(block_is_free(b2))){ /*right adjacent block is free */ b1->size+=b2->size; block_remove(b2); /* remove from dll */ return b1; } else return b1; /* right adjecent is end or not free */ }
// Read and validate the file system bitmap. // // Read all the bitmap blocks into memory. // Set the "bitmap" pointer to point at the beginning of the first // bitmap block. // // Check that all reserved blocks -- 0, 1, and the bitmap blocks themselves -- // are all marked as in-use // (for each block i, assert(!block_is_free(i))). // // Hint: Assume that the superblock has already been loaded into // memory (in variable 'super'). Check out super->s_nblocks. void read_bitmap(void) { int r; int how_many; uint32_t i; char *blk; // Read the bitmap into memory. // The bitmap consists of one or more blocks. A single bitmap block // contains the in-use bits for BLKBITSIZE blocks. There are // super->s_nblocks blocks in the disk altogether. // Set 'bitmap' to point to the first address in the bitmap. // Hint: Use read_block. // LAB 5: Your code here. how_many = super->s_nblocks/BLKBITSIZE; if(super->s_nblocks%BLKBITSIZE) how_many++; if(how_many > 0){ if( (r = read_block(2, &blk)) < 0) panic("Cannot load bitmap!"); bitmap = (uint32_t *)blk; } for(i=1; i<how_many; i++){ if( (r = read_block(i+2, 0)) < 0) panic("Cannot load bitmap!"); } // Make sure the reserved and root blocks are marked in-use. assert(!block_is_free(0)); assert(!block_is_free(1)); assert(bitmap); // Make sure that the bitmap blocks are marked in-use. // LAB 5: Your code here. for(i=0; i<how_many; i++) assert(!block_is_free(i+2)); cprintf("read_bitmap is good\n"); }
// Search the bitmap for a free block and allocate it. When you // allocate a block, immediately flush the changed bitmap block // to disk. // // Return block number allocated on success, // -E_NO_DISK if we are out of blocks. // // Hint: use free_block as an example for manipulating the bitmap. int alloc_block(void) { // The bitmap consists of one or more blocks. A single bitmap block // contains the in-use bits for BLKBITSIZE blocks. There are // super->s_nblocks blocks in the disk altogether. // LAB 5: Your code here. uint32_t blockno; for(blockno = 1; blockno < super->s_nblocks; blockno++) if(block_is_free(blockno)) { bitmap[blockno/32] ^= (1<<(blockno%32)); flush_block(diskaddr(2)); assert(!block_is_free(blockno)); return blockno; } return -E_NO_DISK; }
// Read and validate the file system bitmap. // // Read all the bitmap blocks into memory. // Set the "bitmap" pointer to point at the beginning of the first // bitmap block. // // Check that all reserved blocks -- 0, 1, and the bitmap blocks themselves -- // are all marked as in-use // (for each block i, assert(!block_is_free(i))). // // Hint: Assume that the superblock has already been loaded into // memory (in variable 'super'). Check out super->s_nblocks. void read_bitmap(void) { int r; uint32_t i; char *blk; // Read the bitmap into memory. // The bitmap consists of one or more blocks. A single bitmap block // contains the in-use bits for BLKBITSIZE blocks. There are // super->s_nblocks blocks in the disk altogether. // Set 'bitmap' to point to the first address in the bitmap. // Hint: Use read_block. // LAB 5: Your code here. assert(super); r = read_block(2, &blk); if (r) panic("read_bitmap(): could not read first block: %e\n", r); bitmap = (uint32_t *) blk; for (i = 3; i <= (super->s_nblocks / BLKBITSIZE); i++) { r = read_block(i, NULL); if (r) panic("read_bitmap(): read_block() failed: %e\n", r); } // Make sure the reserved and root blocks are marked in-use. assert(bitmap); assert(!block_is_free(0)); assert(!block_is_free(1)); // Make sure that the bitmap blocks are marked in-use. // LAB 5: Your code here. for (i = 2; i <= (super->s_nblocks / BLKBITSIZE); i++) assert(!block_is_free(i)); cprintf("read_bitmap is good\n"); }
// Fault any disk block that is read or written in to memory by // loading it from disk. // Hint: Use ide_read and BLKSECTS. static void bc_pgfault(struct UTrapframe *utf) { void *addr = (void *) utf->utf_fault_va; uint64_t blockno = ((uint64_t)addr - DISKMAP) / BLKSIZE; int r; // Check that the fault was within the block cache region if (addr < (void*)DISKMAP || addr >= (void*)(DISKMAP + DISKSIZE)) panic("page fault in FS: eip %08x, va %08x, err %04x", utf->utf_rip, addr, utf->utf_err); // Sanity check the block number. if (super && blockno >= super->s_nblocks) panic("reading non-existent block %08x\n", blockno); // Allocate a page in the disk map region, read the contents // of the block from the disk into that page, and mark the // page not-dirty (since reading the data from disk will mark // the page dirty). // // LAB 5: Your code here if((r= sys_page_alloc(0, ROUNDDOWN(addr,PGSIZE), PTE_SYSCALL)) < 0) panic("File System page fault handler couldn't alloc new page at addr %d. %e",addr, r); //if(super) // cprintf("12 %d\n",super->s_nblocks); #ifndef VMM_GUEST if((r = ide_read(blockno*BLKSECTS, ROUNDDOWN(addr,BLKSIZE), BLKSECTS)) < 0) #else if((r = host_read(BLKSECTS*blockno, ROUNDDOWN(addr,BLKSIZE), BLKSECTS)) < 0) #endif panic("File System page fault handler couldn't read in the data from disk. %e", r); //if(super) // cprintf("13 %d\n",super->s_nblocks); if((r = sys_page_map(0, ROUNDDOWN(addr,PGSIZE), 0, ROUNDDOWN(addr,BLKSIZE), PTE_P| PTE_U | PTE_W)) < 0) //PTE_SYSCALL&~PTE_D panic("Couldn't map page not dirty bc_pageflt %e",r); //if(super) // cprintf("14 %d\n",super->s_nblocks); //cprintf("Handled the Fault\n"); //panic("bc_pgfault not implemented"); // Check that the block we read was allocated. (exercise for // the reader: why do we do this *after* reading the block // in?) if (bitmap && block_is_free(blockno)) panic("reading free block %08x\n", blockno); }
// Make sure this block is unmapped. void unmap_block(uint32_t blockno) { int r; if (!block_is_mapped(blockno)) return; assert(block_is_free(blockno) || !block_is_dirty(blockno)); if ((r = sys_page_unmap(0, diskaddr(blockno))) < 0) panic("unmap_block: sys_mem_unmap: %e", r); assert(!block_is_mapped(blockno)); }
// Read and validate the file system bitmap. // // Read all the bitmap blocks into memory. // Set the "bitmap" pointer to point at the beginning of the first // bitmap block. // // Check that all reserved blocks -- 0, 1, and the bitmap blocks themselves -- // are all marked as in-use // (for each block i, assert(!block_is_free(i))). // // Hint: Assume that the superblock has already been loaded into // memory (in variable 'super'). Check out super->s_nblocks. void read_bitmap(void) { int r; uint32_t i; char *blk; for (i = 0; i * BLKBITSIZE < super->s_nblocks; i++) { if ((r = read_block(2+i, &blk)) < 0) panic("cannot read bitmap block %d: %e", i, r); if (i == 0) bitmap = (uint32_t*) blk; // Make sure all bitmap blocks are marked in-use assert(!block_is_free(2+i)); } // Make sure the reserved and root blocks are marked in-use. assert(!block_is_free(0)); assert(!block_is_free(1)); assert(bitmap); cprintf("read_bitmap is good\n"); }
// Search the bitmap for a free block and allocate it. // // Return block number allocated on success, // -E_NO_DISK if we are out of blocks. int alloc_block_num(void) { // LAB 5: Your code here. int i; for (i = 0; i < super->s_nblocks; i++) { if (block_is_free(i)) { bitmap[i / 32] &= ~(1 << (i % 32)); write_block(i / BLKBITSIZE + 2); return i; } } return -E_NO_DISK; }
// Read and validate the file system bitmap. // // Read all the bitmap blocks into memory. // Set the "bitmap" pointer to point at the beginning of the first // bitmap block. // // Check that all reserved blocks -- 0, 1, and the bitmap blocks themselves -- // are all marked as in-use // (for each block i, assert(!block_is_free(i))). // // Hint: Assume that the superblock has already been loaded into // memory (in variable 'super'). Check out super->s_nblocks. void read_bitmap(void) { int r; uint32_t i; char *blk; // Read the bitmap into memory. // The bitmap consists of one or more blocks. A single bitmap block // contains the in-use bits for BLKBITSIZE blocks. There are // super->s_nblocks blocks in the disk altogether. // Set 'bitmap' to point to the first address in the bitmap. // Hint: Use read_block. // LAB 5: Your code here. uint32_t bitmap_blkno = super->s_nblocks / BLKBITSIZE; if(super -> s_nblocks % BLKBITSIZE != 0) bitmap_blkno++; for(i=0;i<bitmap_blkno;i++){ if(read_block(2+i,&blk) < 0) panic("read_bitmap: read_block fail!\n"); } bitmap = (uint32_t *)diskaddr(2); // Make sure the reserved and root blocks are marked in-use. assert(!block_is_free(0)); assert(!block_is_free(1)); assert(bitmap); // Make sure that the bitmap blocks are marked in-use. // LAB 5: Your code here. for(i=0;i<bitmap_blkno;i++) assert(!block_is_free(2+i)); cprintf("read_bitmap is good\n"); }
// Search the bitmap for a free block and allocate it. // // Return block number allocated on success, // -E_NO_DISK if we are out of blocks. int alloc_block_num(void) { // LAB 5: Your code here. int i; for(i=0; i < super->s_nblocks; i++) if (block_is_free(i)){ bitmap[i/32] &= ~(1<<(i%32)); //fancy - ren if(flush_bitmap()) panic("flushing bitmap failed!"); return i; } return -E_NO_DISK; }
// Search the bitmap for a free block and allocate it. // // Return block number allocated on success, // -E_NO_DISK if we are out of blocks. int alloc_block_num(void) { // LAB 5: Your code here. // Search immediately after the bitmap blocks. int i; for (i = 2 + (super->s_nblocks - 1) / BLKBITSIZE + 1; i <= super->s_nblocks; i++) { if (block_is_free(i)) { bitmap[i / 32] ^= 1 << (i % 32); write_block(2 + (i - 1) / BLKBITSIZE); return i; } } return -E_NO_DISK; }
// Fault any disk block that is read in to memory by // loading it from disk. // Hint: Use ide_read and BLKSECTS. static void bc_pgfault(struct UTrapframe *utf) { void *addr = (void *) utf->utf_fault_va; uint64_t blockno = ((uint64_t)addr - DISKMAP) / BLKSIZE; int r; // Check that the fault was within the block cache region if (addr < (void*)DISKMAP || addr >= (void*)(DISKMAP + DISKSIZE)) panic("page fault in FS: eip %08x, va %08x, err %04x", utf->utf_rip, addr, utf->utf_err); // Sanity check the block number. if (super && blockno >= super->s_nblocks) panic("reading non-existent block %08x\n", blockno); // Allocate a page in the disk map region, read the contents // of the block from the disk into that page. // Hint: first round addr to page boundary. // // LAB 5: your code here: addr = ROUNDDOWN(addr, PGSIZE); if(0 != sys_page_alloc(0, (void*)addr, PTE_SYSCALL)){ panic("Page Allocation Failed during handling page fault in FS"); } #ifdef VMM_GUEST if(0 != host_read((uint32_t) (blockno * BLKSECTS), (void*)addr, BLKSECTS)) { panic("ide read failed in Page Fault Handling"); } #else if(0 != ide_read((uint32_t) (blockno * BLKSECTS), (void*)addr, BLKSECTS)) { panic("ide read failed in Page Fault Handling"); } #endif if ((r = sys_page_map(0, addr, 0, addr, uvpt[PGNUM(addr)] & PTE_SYSCALL)) < 0) panic("in bc_pgfault, sys_page_map: %e", r); // Check that the block we read was allocated. (exercise for // the reader: why do we do this *after* reading the block // in?) if (bitmap && block_is_free(blockno)) panic("reading free block %08x\n", blockno); }
// Fault any disk block that is read in to memory by // loading it from disk. static void bc_pgfault(struct UTrapframe *utf) { void *addr = (void *) utf->utf_fault_va; uint32_t blockno = ((uint32_t)addr - DISKMAP) / BLKSIZE; int r; // Check that the fault was within the block cache region if (addr < (void*)DISKMAP || addr >= (void*)(DISKMAP + DISKSIZE)) panic("page fault in FS: eip %08x, va %08x, err %04x", utf->utf_eip, addr, utf->utf_err); // Sanity check the block number. if (super && blockno >= super->s_nblocks) panic("reading non-existent block %08x\n", blockno); // Allocate a page in the disk map region, read the contents // of the block from the disk into that page. // Hint: first round addr to page boundary. fs/ide.c has code to read // the disk. // // LAB 5: you code here: addr = (void *)ROUNDDOWN(addr, PGSIZE); if ((r = sys_page_alloc(0, addr, PTE_P | PTE_U | PTE_W)) < 0) { panic("bc_pgfault: sys_page_alloc error %e\n", r); } if ((r = ide_read(BLKSECTS * blockno, addr, BLKSECTS)) < 0) { panic("bc_pgfault: ide_read error %e\n", r); } // Clear the dirty bit for the disk block page since we just read the // block from disk if ((r = sys_page_map(0, addr, 0, addr, uvpt[PGNUM(addr)] & PTE_SYSCALL)) < 0) panic("in bc_pgfault, sys_page_map: %e", r); // Check that the block we read was allocated. (exercise for // the reader: why do we do this *after* reading the block // in?) if (bitmap && block_is_free(blockno)) panic("reading free block %08x\n", blockno); }
int fs_statfs(const char *path, struct statvfs *stbuf) { int i; memset(stbuf, 0, sizeof(*stbuf)); stbuf->f_bsize = BLKSIZE; stbuf->f_frsize = BLKSIZE; stbuf->f_blocks = super->s_nblocks; stbuf->f_fsid = super->s_magic; stbuf->f_namemax = PATH_MAX; for (i = 0; i < super->s_nblocks; ++i) if (block_is_free(i)) stbuf->f_bfree++; stbuf->f_bavail = stbuf->f_bfree; return 0; }
// Search the bitmap for a free block and allocate it. When you // allocate a block, immediately flush the changed bitmap block // to disk. // // Return block number allocated on success, // -E_NO_DISK if we are out of blocks. // // Hint: use free_block as an example for manipulating the bitmap. int alloc_block(void) { // The bitmap consists of one or more blocks. A single bitmap block // contains the in-use bits for BLKBITSIZE blocks. There are // super->s_nblocks blocks in the disk altogether. // LAB 5: Your code here. int i; for (i = 0; i < super->s_nblocks; ++i) if (block_is_free(i)) { bitmap[i/32] &= (~(1<<(i%32))); flush_block(&bitmap[i/32]); return i; } return -E_NO_DISK; }
// Search the bitmap for a free block and allocate it. When you // allocate a block, immediately flush the changed bitmap block // to disk. // // Return block number allocated on success, // -E_NO_DISK if we are out of blocks. // // Hint: use free_block as an example for manipulating the bitmap. int alloc_block(void) { // The bitmap consists of one or more blocks. A single bitmap block // contains the in-use bits for BLKBITSIZE blocks. There are // super->s_nblocks blocks in the disk altogether. // LAB 5: Your code here. // panic("alloc_block not implemented"); int blkno; for (blkno = 1; blkno < super->s_nblocks; blkno++) { if (block_is_free(blkno)) { bitmap[blkno/32] &= ~(1<<(blkno%32)); flush_block(&bitmap[blkno/32]); return blkno; } } return -E_NO_DISK; }
// Fault any disk block that is read in to memory by // loading it from disk. static void bc_pgfault(struct UTrapframe *utf) { void *addr = (void *) utf->utf_fault_va; uint64_t blockno = ((uint64_t)addr - DISKMAP) / BLKSIZE; int r; // Check that the fault was within the block cache region if (addr < (void*)DISKMAP || addr >= (void*)(DISKMAP + DISKSIZE)) panic("page fault in FS: eip %08x, va %08x, err %04x", utf->utf_rip, addr, utf->utf_err); // Sanity check the block number. if (super && blockno >= super->s_nblocks) panic("reading non-existent block %08x\n", blockno); // Allocate a page in the disk map region, read the contents // of the block from the disk into that page. // Hint: first round addr to page boundary. // // LAB 5: your code here: // Check that the block we read was allocated. (exercise for // the reader: why do we do this *after* reading the block // in?) if (bitmap && block_is_free(blockno)) //doubtful panic("reading free block %08x\n", blockno); void *new_addr = ROUNDDOWN(addr, PGSIZE); r = sys_page_alloc(0, new_addr, PTE_P|PTE_W|PTE_U); if(r<0) panic("Something wrong with allocation %e",r); uint64_t sec_no = BLKSECTS * blockno; size_t nsecs = BLKSECTS; #ifdef VMM_GUEST r = host_read(sec_no, new_addr, nsecs); #else r = ide_read(sec_no, new_addr, nsecs); #endif if(r<0) panic("Something wrong with reading from the disk %e",r); }