Beispiel #1
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
    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);
}
Beispiel #2
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)
{
	// 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");
}
Beispiel #4
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)
{
	// 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;
}
Beispiel #5
0
// 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);
}
Beispiel #6
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)
{
	// 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;
}
Beispiel #7
0
// 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;
}
Beispiel #8
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)
{
	// 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);
}
Beispiel #10
0
// 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);
}
Beispiel #11
0
// 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);
}
Beispiel #12
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);
}
Beispiel #13
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);
}
Beispiel #14
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);
}
Beispiel #15
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;
}
Beispiel #16
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;
}
Beispiel #17
0
// 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);
}
Beispiel #18
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);
}
Beispiel #19
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)
{
	// 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);	
}
Beispiel #20
0
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;
}
Beispiel #21
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.
    //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;
}
Beispiel #22
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)
{
	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;
}
Beispiel #23
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);
}
Beispiel #24
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");
}
Beispiel #26
0
// 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;	
}
Beispiel #27
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)
{
	// 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;
}
Beispiel #28
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.
  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;
}
Beispiel #29
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)
{
    // 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");
}