// Open a file (or directory). // // Returns: // The file descriptor index on success // -E_BAD_PATH if the path is too long (>= MAXPATHLEN) // < 0 for other errors. int open(const char *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 struct Fd *f = NULL; int r = 0; if (!path) return -E_INVAL; if((r=fd_alloc(&f))<0) return r; strcpy(fsipcbuf.open.req_path, path); fsipcbuf.open.req_omode = mode; if ((r=fsipc(FSREQ_OPEN, f))<0) { fd_close(f, 0); return r; } return fd2num(f); }
// Write at most 'n' bytes from 'buf' to 'fd' at the current seek position. // // Returns: // The number of bytes successfully written. // < 0 on error. static ssize_t devfile_write(struct Fd *fd, const void *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 result; if(sizeof(fsipcbuf.write.req_buf) < n) { n=sizeof(fsipcbuf.write.req_buf); } fsipcbuf.write.req_n=n; fsipcbuf.write.req_fileid=fd->fd_file.id; memmove(fsipcbuf.write.req_buf, buf, n); result=fsipc(FSREQ_WRITE, NULL); return result; }
// Open a file (or directory). // // Returns: // The file descriptor index on success // -E_BAD_PATH if the path is too long (>= MAXPATHLEN) // < 0 for other errors. int open(const char *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. // LAB 5: Your code here. struct Fd* retval; int r = fd_alloc(&retval); if(r<0) return r; fsipcbuf.open.req_omode = mode; strcpy(fsipcbuf.open.req_path, path); r = fsipc(FSREQ_OPEN, retval); if (r<0) { fd_close(retval, 0); return r; } return fd2num(retval); // panic("open not implemented"); }
// Write at most 'n' bytes from 'buf' to 'fd' at the current seek position. // // Returns: // The number of bytes successfully written. // < 0 on error. static ssize_t devfile_write(struct Fd *fd, const void *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 int r; fsipcbuf.write.req_fileid = fd->fd_file.id; size_t offset = 0; size_t left_size = n; size_t buff_size = PGSIZE - (sizeof(int) + sizeof(size_t)); while(left_size > 0) { size_t copy_size = left_size > buff_size ? buff_size : left_size; memmove(fsipcbuf.write.req_buf, (char *)buf + offset, copy_size); fsipcbuf.write.req_n = copy_size; if ((r = fsipc(FSREQ_WRITE, NULL)) < 0) { return r; } else if(r > 0) { offset += r; left_size -= r; } else if(r == 0) { break; } } assert(offset <= n); return offset; }
// Truncate or extend an open file to 'size' bytes static int devfile_trunc(struct Fd *fd, off_t newsize) { fsipcbuf.set_size.req_fileid = fd->fd_file.id; fsipcbuf.set_size.req_size = newsize; return fsipc(FSREQ_SET_SIZE, NULL); }
// Write at most 'n' bytes from 'buf' to 'fd' at the current seek position. // // Returns: // The number of bytes successfully written. // < 0 on error. static ssize_t devfile_write(struct Fd *fd, const void *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. // code for lab 5 -M.G // panic("devfile_write not implemented"); // size_t num_bytes = MAX(n, PGSIZE - (sizeof(int) + sizeof(size_t)); int return_value; uint32_t size = PGSIZE - (sizeof(int) + sizeof(size_t)); if (n > size) { n = size; } fsipcbuf.write.req_fileid = fd->fd_file.id; fsipcbuf.write.req_n = n; memmove(fsipcbuf.write.req_buf, buf, n); return_value = fsipc(FSREQ_WRITE, NULL); return return_value; }
// Read at most 'n' bytes from 'fd' at the current position into 'buf'. // // Returns: // The number of bytes successfully read. // < 0 on error. static ssize_t devfile_read(struct Fd *fd, void *buf, size_t n) { // Make an FSREQ_READ request to the file system server after // filling fsipcbuf.read with the request arguments. The // bytes read will be written back to fsipcbuf by the file // system server. // LAB 5: Your code here //panic("devfile_read not implemented"); int result; fsipcbuf.read.req_n=n; fsipcbuf.read.req_fileid=fd->fd_file.id; if((result=fsipc(FSREQ_READ, NULL)) < 0) { return result; } else { memmove(buf, fsipcbuf.readRet.ret_buf, result); } return result; }
// Write at most 'n' bytes from 'buf' to 'fd' at the current seek position. // // Returns: // The number of bytes successfully written. // < 0 on error. static ssize_t devfile_write(struct Fd *fd, const void *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 fsipcbuf.write.req_fileid = (fd -> fd_file).id; fsipcbuf.write.req_n = n; int buffer_size = sizeof(struct Fsreq_write)-(sizeof(int) + sizeof(size_t)); size_t bytes_written = fsipcbuf.write.req_n < buffer_size ? fsipcbuf.write.req_n : buffer_size; memmove(fsipcbuf.write.req_buf, (void*)buf, bytes_written); //strncpy(fsipcbuf.write.req_buf, buf, bytes_written); int r = 0; if((r = fsipc(FSREQ_WRITE, NULL)) < 0) { return r; } return r; panic("devfile_write not implemented"); }
// Delete a file int remove(const char *path) { if (strlen(path) >= MAXPATHLEN) return -E_BAD_PATH; strcpy(fsipcbuf.remove.req_path, path); return fsipc(FSREQ_REMOVE, NULL); }
// Synchronize disk with buffer cache int sync(void) { // Ask the file server to update the disk // by writing any dirty blocks in the buffer cache. return fsipc(FSREQ_SYNC, NULL); }
// Make a file-close request to the file server. // After this the fileid is invalid. int fsipc_close(int fileid) { struct Fsreq_close *req; req = (struct Fsreq_close*) fsipcbuf; req->req_fileid = fileid; return fsipc(FSREQ_CLOSE, req, 0, 0); }
// Ask the file server to mark a particular file block dirty. int fsipc_dirty(int fileid, off_t offset) { struct Fsreq_dirty *req; req = (struct Fsreq_dirty*) fsipcbuf; req->req_fileid = fileid; req->req_offset = offset; return fsipc(FSREQ_DIRTY, req, 0, 0); }
// Make a set-file-size request to the file server. int fsipc_set_size(int fileid, off_t size) { struct Fsreq_set_size *req; req = (struct Fsreq_set_size*) fsipcbuf; req->req_fileid = fileid; req->req_size = size; return fsipc(FSREQ_SET_SIZE, req, 0, 0); }
// Ask the file server to delete a file, given its pathname. int fsipc_remove(const char *path) { struct Fsreq_remove *req; req = (struct Fsreq_remove*) fsipcbuf; if (strlen(path) >= MAXPATHLEN) return -E_BAD_PATH; strcpy(req->req_path, path); return fsipc(FSREQ_REMOVE, req, 0, 0); }
static int devfile_stat(struct Fd *fd, struct Stat *st) { int r; fsipcbuf.stat.req_fileid = fd->fd_file.id; if ((r = fsipc(FSREQ_STAT, NULL)) < 0) return r; strcpy(st->st_name, fsipcbuf.statRet.ret_name); st->st_size = fsipcbuf.statRet.ret_size; st->st_isdir = fsipcbuf.statRet.ret_isdir; return 0; }
// Make a map-block request to the file server. // We send the fileid and the (byte) offset of the desired block in the file, // and the server sends us back a mapping for a page containing that block. // Returns 0 on success, < 0 on failure. int fsipc_map(int fileid, off_t offset, void *dstva) { // LAB 5: Your code here. int perm; struct Fsreq_map *req; req = (struct Fsreq_map*) fsipcbuf; req->req_fileid = fileid; req->req_offset = offset; int r= fsipc(FSREQ_MAP, req, dstva, &perm); return r; }
// Ask the file server to mark a particular file block dirty. int fsipc_dirty(int fileid, off_t offset) { // LAB 5: Your code here. //panic("fsipc_dirty not implemented"); //return -E_UNSPECIFIED; int perm; struct Fsreq_dirty *req; req = (struct Fsreq_dirty*)fsipcbuf; req->req_fileid = fileid; req->req_offset = offset; return fsipc(FSREQ_DIRTY, req, 0, 0); }
// Send file-open request to the file server. // Includes 'path' and 'omode' in request, // and on reply maps the returned file descriptor page // at the address indicated by the caller in 'fd'. // Returns 0 on success, < 0 on failure. int fsipc_open(const char *path, int omode, struct Fd *fd) { int perm; struct Fsreq_open *req; req = (struct Fsreq_open*)fsipcbuf; if (strlen(path) >= MAXPATHLEN) return -E_BAD_PATH; strcpy(req->req_path, path); req->req_omode = omode; return fsipc(FSREQ_OPEN, req, fd, &perm); }
// Write at most 'n' bytes from 'buf' to 'fd' at the current seek position. // // Returns: // The number of bytes successfully written. // < 0 on error. static ssize_t devfile_write(struct Fd *fd, const void *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 fsipcbuf.write.req_fileid = fd->fd_file.id; fsipcbuf.write.req_n = n; memmove(fsipcbuf.write.req_buf, buf, MIN(n, PGSIZE - sizeof(int) - sizeof(size_t))); return fsipc(FSREQ_WRITE, NULL); }
static ssize_t devfile_write(struct Fd *fd, const void *buf, size_t n) { ssize_t r,status; fsipcbuf.write.req_fileid = fd -> fd_file.id; //fsipcbuf.write.req_n=n; if(n > (PGSIZE - (sizeof(int) + sizeof(size_t)))) n = (PGSIZE - (sizeof(int) + (sizeof(size_t)))); fsipcbuf.write.req_n=n; memmove(fsipcbuf.write.req_buf, buf, n); r = fsipc(FSREQ_WRITE, NULL); return r; }
// Make a map-block request to the file server. // We send the fileid and the (byte) offset of the desired block in the file, // and the server sends us back a mapping for a page containing that block. // Returns 0 on success, < 0 on failure. int fsipc_map(int fileid, off_t offset, void *dstva) { // LAB 5: Your code here. //panic("fsipc_map not implemented"); int perm; struct Fsreq_map *req; req = (struct Fsreq_map*)fsipcbuf; req->req_fileid = fileid; req->req_offset = offset; return fsipc(FSREQ_MAP, req, dstva, &perm); //return -E_UNSPECIFIED; }
// Make a map-block request to the file server. // We send the fileid and the (byte) offset of the desired block in the file, // and the server sends us back a mapping for a page containing that block. // Returns 0 on success, < 0 on failure. int fsipc_map(int fileid, off_t offset, void *dstva) { int r, perm; struct Fsreq_map *req; req = (struct Fsreq_map*) fsipcbuf; req->req_fileid = fileid; req->req_offset = offset; if ((r = fsipc(FSREQ_MAP, req, dstva, &perm)) < 0) return r; if ((perm & ~(PTE_W | PTE_SHARE)) != (PTE_U | PTE_P)) panic("fsipc_map: unexpected permissions %08x for dstva %08x", perm, dstva); return 0; }
// Write at most 'n' bytes from 'buf' to 'fd' at the current seek position. // // Returns: // The number of bytes successfully written. // < 0 on error. static ssize_t devfile_write(struct Fd *fd, const void *buf, size_t n) { if(n > sizeof(fsipcbuf.write.req_buf)) n = sizeof(fsipcbuf.write.req_buf); fsipcbuf.write.req_fileid = fd->fd_file.id; fsipcbuf.write.req_n = n; int i = 0; while(i < n){ fsipcbuf.write.req_buf[i] = ((char *)buf)[i]; i++; } return fsipc(FSREQ_WRITE, 0); }
// Open a file (or directory). // // Returns: // The file descriptor index on success // -E_BAD_PATH if the path is too long (>= MAXPATHLEN) // < 0 for other errors. int open(const char *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. // LAB 5: Your code here. //panic("open not implemented"); int result; struct Fd *fd_instance; if(strlen(path) >= MAXPATHLEN) { cprintf("open() error: path is too long"); return -E_BAD_PATH; } if((result=fd_alloc(&fd_instance)) < 0) { return result; } strcpy(fsipcbuf.open.req_path, path); fsipcbuf.open.req_omode=mode; if((result=fsipc(FSREQ_OPEN, (void *)fd_instance)) < 0) { fd_close(fd_instance, 0); return result; } else { return fd2num(fd_instance); } }
// Write at most 'n' bytes from 'buf' to 'fd' at the current seek position. // // Returns: // The number of bytes successfully written. // < 0 on error. static ssize_t devfile_write(struct Fd *fd, const void *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. int r; fsipcbuf.write.req_fileid = fd->fd_file.id; if (n > PGSIZE) n = PGSIZE; //TODO: How to deal with this? fsipcbuf.write.req_n = n; memcpy(fsipcbuf.write.req_buf, buf, n); return fsipc(FSREQ_WRITE, NULL); panic("devfile_write not implemented"); }
// Read at most 'n' bytes from 'fd' at the current position into 'buf'. // // Returns: // The number of bytes successfully read. // < 0 on error. static ssize_t devfile_read(struct Fd *fd, void *buf, size_t n) { // Make an FSREQ_READ request to the file system server after // filling fsipcbuf.read with the request arguments. The // bytes read will be written back to fsipcbuf by the file // system server. // LAB 5: Your code here int r; fsipcbuf.read.req_fileid = fd->fd_file.id; fsipcbuf.read.req_n = n; if((r = fsipc(FSREQ_READ, NULL)) < 0) return r; memmove(buf, fsipcbuf.readRet.ret_buf, r); return r; }
// Write at most 'n' bytes from 'buf' to 'fd' at the current seek position. // // Returns: // The number of bytes successfully written. // < 0 on error. static ssize_t devfile_write(struct Fd *fd, const void *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; size_t cnt = 0, buf_size = sizeof(fsipcbuf.write.req_buf); while (cnt < n) { fsipcbuf.write.req_n = buf_size < (n - cnt) ? buf_size : (n - cnt); memmove(fsipcbuf.write.req_buf, buf, fsipcbuf.write.req_n); if ((r = fsipc(FSREQ_WRITE, NULL)) < 0) { return r; } cnt += r; } return cnt; }
// Open a file (or directory). // // Returns: // The file descriptor index on success // -E_BAD_PATH if the path is too long (>= MAXPATHLEN) // < 0 for other errors. int open(const char *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. // LAB 5: Your code here. int r; struct Fd *fd; r = fd_alloc(&fd); if (r < 0) return r; // DO NOT ALLOCATE !! //r = sys_page_alloc(0, fd, PTE_U|PTE_W|PTE_P); //if (r < 0) goto out; if (strlen(path) >= MAXPATHLEN) return -E_BAD_PATH; strcpy(fsipcbuf.open.req_path, path); fsipcbuf.open.req_omode = mode; r = fsipc(FSREQ_OPEN, fd); if (r < 0) goto out; return fd2num(fd); out: assert(fd_close(fd, 0) == 0); return r; }
// Write at most 'n' bytes from 'buf' to 'fd' at the current seek position. // // Returns: // The number of bytes successfully written. // < 0 on error. static ssize_t devfile_write(struct Fd *fd, const void *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 int r; fsipcbuf.write.req_fileid = fd->fd_file.id; fsipcbuf.write.req_n = n; // copy data to be sent from buf to struct write memcpy(fsipcbuf.write.req_buf, buf, n); if ((r = fsipc(FSREQ_WRITE, NULL)) < 0) return r; assert(r <= n); assert(r < PGSIZE - (sizeof(int) + sizeof(size_t))); fd->fd_offset += r; return r; }
// Open a file (or directory). // // Returns: // The file descriptor index on success // -E_BAD_PATH if the path is too long (>= MAXPATHLEN) // < 0 for other errors. int open(const char *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. if (strlen(path) > MAXPATHLEN) return -E_BAD_PATH; struct Fd *fd; int r; 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) { fd_close(fd, 0); return r; } return fd2num(fd); panic("open not implemented"); }