structSuper { uint32_t s_magic; // Magic number: FS_MAGIC uint32_t s_nblocks; // Total number of blocks on disk structFiles_root;// Root directory node };
structFile { char f_name[MAXNAMELEN]; // filename off_t f_size; // file size in bytes uint32_t f_type; // file type
// Block pointers. // A block is allocated iff its value is != 0. uint32_t f_direct[NDIRECT]; // direct blocks uint32_t f_indirect; // indirect block
// Pad out to 256 bytes; must do arithmetic in case we're compiling // fsformat on a 64-bit machine. uint8_t f_pad[256 - MAXNAMELEN - 8 - 4*NDIRECT - 4]; } __attribute__((packed)); // required only on some 64-bit machines
// If this is the file server (type == ENV_TYPE_FS) give it I/O privileges. // LAB 5: Your code here. structEnv *e; int ret; if(env_alloc(&e,0) != 0){ panic("env_alloc(): env_alloc failed!\n"); } if(type == ENV_TYPE_FS){ e->env_tf.tf_eflags |= FL_IOPL_MASK; }
// 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 = ROUNDDOWN(addr,PGSIZE); sys_page_alloc(0, addr, PTE_W|PTE_U|PTE_P); uint32_t secnum = blockno * BLKSECTS; if((r = ide_read(secnum,addr,BLKSECTS)) < 0){ panic("ide_read(): %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 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.
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; fsipcbuf.write.req_fileid = fd->fd_file.id; fsipcbuf.write.req_n = n; memmove(fsipcbuf.write.req_buf,buf,n); return fsipc(FSREQ_WRITE,NULL); }
int open(constchar *path, int mode) { // Find an unused file descriptor page using fd_alloc. // Then send a file-open request to the file server. // Include 'path' and 'omode' in request, // and map the returned file descriptor page // at the appropriate fd address. // FSREQ_OPEN returns 0 on success, < 0 on failure. // // (fd_alloc does not allocate a page, it just returns an // unused fd address. Do you need to allocate a page?) // // Return the file descriptor index. // If any step after fd_alloc fails, use fd_close to free the // file descriptor. int r; structFd *fd; if (strlen(path) >= MAXPATHLEN) //文件名不能超过指定长度 return -E_BAD_PATH; if ((r = fd_alloc(&fd)) < 0) //搜索当前进程未被分配的文件描述符 return r; strcpy(fsipcbuf.open.req_path, path); fsipcbuf.open.req_omode = mode; if ((r = fsipc(FSREQ_OPEN, fd)) < 0) { //通过fsipc()向FS进程发起RPC调用 fd_close(fd, 0); return r; } return fd2num(fd); }