// Clean up a file-server file descriptor. // This function is called by fd_close. static int file_close(struct Fd *fd) { // Unmap any data mapped for the file, // then tell the file server that we have closed the file // (to free up its resources). // LAB 5: Your code here. void *va; void *start; void *end; int r; start=(void *)fd2data(fd); end=(void *)(start + fd->fd_file.file.f_size); for (va=(void *)fd2data(fd); va <= end; va+=PGSIZE) if (va_is_dirty2(va)) if ((r = fsipc_dirty(fd->fd_file.id, (off_t) (va - start))) < 0) return r; if ((r = fsipc_close(fd->fd_file.id)) < 0) return r; funmap(fd, fd->fd_file.file.f_size, 0, 0); return 0; }
// Unmap any file pages that no longer represent valid file pages // when the size of the file as mapped in our address space decreases. // Harmlessly does nothing if newsize >= oldsize. static int funmap(struct Fd* fd, off_t oldsize, off_t newsize, bool dirty) { size_t i; char *va; int r, ret; va = fd2data(fd); // Check vpd to see if anything is mapped. if (!(vpd[VPD(va)] & PTE_P)) return 0; ret = 0; for (i = ROUNDUP(newsize, PGSIZE); i < oldsize; i += PGSIZE) if (vpt[VPN(va + i)] & PTE_P) { if (dirty && (vpt[VPN(va + i)] & PTE_D) && (r = fsipc_dirty(fd->fd_file.id, i)) < 0) ret = r; sys_page_unmap(0, va + i); } return ret; }
// Unmap any file pages that no longer represent valid file pages // when the size of the file as mapped in our address space decreases. // Harmlessly does nothing if newsize >= oldsize. static int funmap(struct Fd* fd, off_t oldsize, off_t newsize, bool dirty) { size_t i; char *va; int r, ret; // For each page that needs to be unmapped, notify the server if // the page is dirty and remove the page. // Hint: Use vpt to check if a page need to be unmapped. // LAB 5: Your code here. ret = 0; va = fd2data(fd); for (i = ROUNDUP(newsize, PGSIZE); i < oldsize; i += PGSIZE) if (vpt[VPN(va + i)] & PTE_P) { if (dirty && (vpt[VPN(va)] & PTE_D) && (r = fsipc_dirty(fd->fd_file.id, i)) < 0) ret = r; sys_page_unmap(0, va + i); } return ret; }