Finish lab 5.

This commit is contained in:
2019-05-16 18:50:16 -07:00
parent e9f683f6d6
commit 4199ce9c37
10 changed files with 139 additions and 20 deletions

17
fs/bc.c
View File

@@ -31,6 +31,7 @@ bc_pgfault(struct UTrapframe *utf)
{
void *addr = (void *) utf->utf_fault_va;
uint32_t blockno = ((uint32_t)addr - DISKMAP) / BLKSIZE;
uint32_t secno = blockno * (BLKSIZE / SECTSIZE);
int r;
// Check that the fault was within the block cache region
@@ -48,6 +49,11 @@ bc_pgfault(struct UTrapframe *utf)
// the disk.
//
// LAB 5: you code here:
addr = ROUNDDOWN(addr, PGSIZE);
if((r = sys_page_alloc(0, addr, PTE_U | PTE_W | PTE_P)) < 0)
panic("failed to allocate page for block cache");
if((r = ide_read(secno, addr, BLKSIZE / SECTSIZE)) < 0)
panic("failed to read from disk into block cache");
// Clear the dirty bit for the disk block page since we just read the
// block from disk
@@ -72,12 +78,21 @@ void
flush_block(void *addr)
{
uint32_t blockno = ((uint32_t)addr - DISKMAP) / BLKSIZE;
uint32_t secno = blockno * (BLKSIZE / SECTSIZE);
int r;
if (addr < (void*)DISKMAP || addr >= (void*)(DISKMAP + DISKSIZE))
panic("flush_block of bad va %08x", addr);
// LAB 5: Your code here.
panic("flush_block not implemented");
addr = ROUNDDOWN(addr, PGSIZE);
if(!(va_is_mapped(addr) && va_is_dirty(addr))) return;
if((r = ide_write(secno, addr, BLKSIZE / SECTSIZE)) < 0)
panic("failed to flush block into cache");
if((r = sys_page_map(0, addr, 0, addr, uvpt[PGNUM(addr)] & PTE_SYSCALL)) < 0)
panic("failed to remove dirty bit from page");
}
// Test that the block cache works, by smashing the superblock and

42
fs/fs.c
View File

@@ -60,9 +60,15 @@ 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.
uint32_t* search = bitmap + 1;
for(uint32_t block = 1; block < super->s_nblocks; block++) {
if(bitmap[block / 32] & (1 << (block % 32))) {
bitmap[block / 32] &= ~(1 << (block % 32));
flush_block(&bitmap[block / 32]);
return block;
}
}
// LAB 5: Your code here.
panic("alloc_block not implemented");
return -E_NO_DISK;
}
@@ -135,7 +141,23 @@ static int
file_block_walk(struct File *f, uint32_t filebno, uint32_t **ppdiskbno, bool alloc)
{
// LAB 5: Your code here.
panic("file_block_walk not implemented");
int newblock;
if(filebno < NDIRECT) {
*ppdiskbno = &f->f_direct[filebno];
return 0;
} else if(filebno < NDIRECT + NINDIRECT) {
filebno -= NDIRECT;
if(!f->f_indirect) {
if(!alloc) return -E_NOT_FOUND;
if((newblock = alloc_block()) < 0) return newblock;
f->f_indirect = newblock;
}
uint32_t* indirect = diskaddr(f->f_indirect);
*ppdiskbno = &indirect[filebno];
return 0;
}
return -E_INVAL;
}
// Set *blk to the address in memory where the filebno'th
@@ -150,7 +172,19 @@ int
file_get_block(struct File *f, uint32_t filebno, char **blk)
{
// LAB 5: Your code here.
panic("file_get_block not implemented");
uint32_t* blockno;
int r;
if ((r = file_block_walk(f, filebno, &blockno, 1)) < 0)
return r;
if(*blockno == 0) {
if((r = alloc_block()) < 0) return r;
*blockno = r;
}
*blk = diskaddr(*blockno);
return 0;
}
// Try to find a file named "name" in dir. If so, set *file to it.

View File

@@ -209,12 +209,20 @@ serve_read(envid_t envid, union Fsipc *ipc)
{
struct Fsreq_read *req = &ipc->read;
struct Fsret_read *ret = &ipc->readRet;
struct OpenFile* open_file;
int r;
if (debug)
cprintf("serve_read %08x %08x %08x\n", envid, req->req_fileid, req->req_n);
// Lab 5: Your code here:
return 0;
if((r = openfile_lookup(envid, req->req_fileid, &open_file)) < 0)
return r;
if((r = file_read(open_file->o_file, ret->ret_buf, req->req_n, open_file->o_fd->fd_offset)) < 0)
return r;
open_file->o_fd->fd_offset += r;
return r;
}
@@ -227,9 +235,17 @@ serve_write(envid_t envid, struct Fsreq_write *req)
{
if (debug)
cprintf("serve_write %08x %08x %08x\n", envid, req->req_fileid, req->req_n);
struct OpenFile* open_file;
int r;
// LAB 5: Your code here.
panic("serve_write not implemented");
if((r = openfile_lookup(envid, req->req_fileid, &open_file)) < 0)
return r;
if((r = file_write(open_file->o_file, req->req_buf, req->req_n, open_file->o_fd->fd_offset)) < 0)
return r;
open_file->o_fd->fd_offset += r;
return r;
}
// Stat ipc->stat.req_fileid. Return the file's struct Stat to the