if (type == ENV_TYPE_FS) e->env_tf.tf_eflags |= FL_IOPL_MASK;
Q: Do you have to do anything else to ensure that this I/O privilege setting is saved and restored properly when you subsequently switch from one environment to another? Why?
// 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 = ROUNDDOWN(addr, BLKSIZE); if (r = sys_page_alloc(0, addr, PTE_P | PTE_U | PTE_W), r < 0) panic("in bc_pgfault, sys_page_alloc: %e", r); if (r = ide_read(blockno * BLKSECTS, addr, BLKSECTS), r < 0) panic("in bc_pgfault, ide_read: %e", 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?) // perhaps it's the bitmap block, therefore reading the block before checking the bitmap if (bitmap && block_is_free(blockno)) panic("reading free block %08x\n", blockno);
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 blockno;
if (!super) panic("no super block");
for (blockno = 0; blockno < super->s_nblocks; ++blockno) if (block_is_free(blockno)) break; if (blockno == super->s_nblocks) return -E_NO_DISK;
staticssize_t devfile_write(struct Fd *fd, constvoid *buf, size_t n) { // Make an FSREQ_WRITE request to the file system server. Be // careful: fsipcbuf.write.req_buf is only so large, but // remember that write is always allowed to write *fewer* // bytes than requested. // LAB 5: Your code here // panic("devfile_write not implemented"); int r;
staticint sys_env_set_trapframe(envid_t envid, struct Trapframe *tf) { // LAB 5: Your code here. // Remember to check whether the user has supplied us with a good // address! // panic("sys_env_set_trapframe not implemented"); int r; structEnv *e;
internal FS tests [fs/test.c]: OK (1.4s) fs i/o: OK check_bc: OK check_super: OK check_bitmap: OK alloc_block: OK file_open: OK file_get_block: OK file_flush/file_truncate/file rewrite: OK testfile: OK (1.3s) serve_open/file_stat/file_close: OK file_read: OK file_write: OK file_read after file_write: OK open: OK large file: OK spawn via spawnhello: OK (0.7s) Protection I/O space: OK (1.6s) PTE_SHARE [testpteshare]: OK (2.3s) PTE_SHARE [testfdsharing]: OK (1.1s) start the shell [icode]: Timeout! OK (31.4s) testshell: OK (1.9s) primespipe: OK (6.8s) Score: 150/150
return0; } // 驱逐一些缓存块 staticint bufc_evict(void) { int r;
EmbedLink *ln; // 驱逐所有Access位为0的块 for (ln = bufc_used.next; ln != &bufc_used;) { BufferCache *bc = master(ln, BufferCache, bufc_used_link); void *addr = bc->bufc_addr; ln = ln->next; if (!(uvpt[PGNUM(addr)] & PTE_A)) { if (r = bufc_remove(bc), r < 0) return r; } } // 如果失败,则驱逐最早进入缓存的块 if (ncache == NCACHE) { ln = bufc_used.next; assert(ln != &bufc_used); BufferCache *bc = master(ln, BufferCache, bufc_used_link); if (r = bufc_remove(bc), r < 0) return r; }
return0; }
顺便在free_block时也将其映射的页释放:
1 2 3 4 5 6 7 8 9 10 11 12 13
// Mark a block free in the bitmap void free_block(uint32_t blockno) { int r; // Blockno zero is the null pointer of block numbers. if (blockno == 0) panic("attempt to free zero block"); bitmap[blockno/32] |= 1<<(blockno%32); // 释放缓存 if (r = sys_page_unmap(0, diskaddr(blockno)), r < 0) panic("free_block: %e", r); }
internal FS tests [fs/test.c]: OK (1.4s) fs i/o: OK check_bc: OK check_super: OK check_bitmap: OK alloc_block: OK file_open: OK file_get_block: OK file_flush/file_truncate/file rewrite: OK testfile: OK (1.1s) serve_open/file_stat/file_close: OK file_read: OK file_write: OK file_read after file_write: OK open: OK large file: OK spawn via spawnhello: OK (1.7s) (Old jos.out.spawn failure log removed) Protection I/O space: OK (1.0s) PTE_SHARE [testpteshare]: OK (1.8s) (Old jos.out.pte_share failure log removed) PTE_SHARE [testfdsharing]: OK (2.2s) start the shell [icode]: Timeout! OK (31.8s) testshell: OK (1.9s) primespipe: OK (5.5s) Score: 150/150