Esempio n. 1
0
/*
 * sys_getdirentry
 */
int
sys_getdirentry(int fd, userptr_t buf, size_t buflen, int *retval)
{
    DEBUG(DB_VFS, "*** getdirentry %d\n", fd);
	struct vnode *vn;
	off_t offset = 0;
	int err;
	struct uio my_uio;
	struct iovec uio_iov;

	/* Check if fd is a valid file descriptor. */
    struct filetable *ft = curthread->t_filetable;
    spinlock_acquire(&ft->ft_spinlock);
    
    /* If fd is not a valid file descriptor, or was not opened for reading,
     * return error */
    if ((fd < 0) || (fd >= __OPEN_MAX) || (ft->ft_entries[fd] == NULL) ||
            (ft->ft_entries[fd]->ft_vnode == NULL)) {
        spinlock_release(&ft->ft_spinlock);
        return EBADF;
    }
    int how = ft->ft_entries[fd]->ft_flags & O_ACCMODE;
    if ((how != O_RDONLY) && (how != O_RDWR)) {
        spinlock_release(&ft->ft_spinlock);
        return EBADF;
    }

	/* Initialize vn and offset using your filetable info for fd */
    vn = ft->ft_entries[fd]->ft_vnode;
    offset = ft->ft_entries[fd]->ft_pos;

	/* set up a uio with the buffer, its size, and the current offset */
	mk_useruio(&uio_iov, &my_uio, buf, buflen, offset, UIO_READ);

	/* does the read */
	err = VOP_GETDIRENTRY(vn, &my_uio);
	if (err) {
        spinlock_release(&ft->ft_spinlock);
		return err;
	}

	/* Set the offset to the updated offset in the uio. 
	 * Save the new offset with your filetable info for fd.
	 */
	offset = my_uio.uio_offset;
    ft->ft_entries[fd]->ft_pos = offset;
	
	/*
	 * the amount read is the size of the buffer originally, minus
	 * how much is left in it. Note: it is not correct to use
	 * uio_offset for this!
	 */
	*retval = buflen - my_uio.uio_resid;
    spinlock_release(&ft->ft_spinlock);
	return 0;
}
Esempio n. 2
0
//   spinlock_acquire(&ft->filetable_lock);
//   // update file seeking position
//   ft->ft_entries[fd]->pos += *retval;
//   spinlock_release(&ft->filetable_lock);
//   return 0;
// }
int
sys_read(int fd, userptr_t buf, size_t size, int *retval)
{
  struct uio user_uio;
  struct iovec user_iov;
  int result;

  // Check fd is a valid file handle
  if ((fd < 0) || (fd >= __OPEN_MAX)){
    return EBADF;
  }
  struct filetable *ft = curthread->t_filetable;
  spinlock_acquire(&ft->filetable_lock);

  // Check fd is a valid file handle in filetable and the vnode is not empty
  if ((ft->ft_entries[fd] == NULL) || (ft->ft_entries[fd]->file_vnode == NULL)) {
    spinlock_release(&ft->filetable_lock);
    return EBADF;
  }

  // Check the file handle has the permission to read
  int fl = ft->ft_entries[fd]->flags & O_ACCMODE;
  if ((fl != O_RDONLY) && (fl != O_RDWR)) {
    spinlock_release(&ft->filetable_lock);
    return EBADF;
  }

  // Init the offset by the position of the file handle
  int offset = ft->ft_entries[fd]->pos;

  /* set up a uio with the buffer, its size, and the current offset */
  mk_useruio(&user_iov, &user_uio, buf, size, offset, UIO_READ);
  // before read you do the vop_read you have to release the lock
  spinlock_release(&ft->filetable_lock);
  /* does the read */
  result = VOP_READ(ft->ft_entries[fd]->file_vnode, &user_uio);
  if (result) {
    spinlock_release(&ft->filetable_lock);
    return result;
  }

  /*
   * The amount read is the size of the buffer originally, minus
   * how much is left in it.
   */
  *retval = size - user_uio.uio_resid;

  ft->ft_entries[fd]->pos += *retval;
  spinlock_release(&ft->filetable_lock);

  return 0;
}
Esempio n. 3
0
/*
 * sys_read
 * calls VOP_READ.
 * 
 * A4: This is the "dumb" implementation of sys_write:
 * it only deals with file descriptors 1 and 2, and 
 * assumes they are permanently associated with the 
 * console vnode (which must have been previously initialized).
 *
 * In your implementation, you should use the file descriptor
 * to find a vnode from your file table, and then read from it.
 *
 * Note that any problems with the address supplied by the
 * user as "buf" will be handled by the VOP_READ / uio code
 * so you do not have to try to verify "buf" yourself.
 *
 * Most of this code should be replaced.
 */
int
sys_read(int fd, userptr_t buf, size_t size, int *retval)
{
	DEBUG(DB_VFS, "*** Reading fd %d\n", fd);
    
    struct uio user_uio;
	struct iovec user_iov;
	int result;
	int offset = 0;

    /* Check if fd is a valid file descriptor. */
    struct filetable *ft = curthread->t_filetable;
    spinlock_acquire(&ft->ft_spinlock);
    
    /* If fd is not a valid file descriptor, or was not opened for reading,
     * return error */
    if ((fd < 0) || (fd >= __OPEN_MAX) || (ft->ft_entries[fd] == NULL) ||
            (ft->ft_entries[fd]->ft_vnode == NULL)) {
        spinlock_release(&ft->ft_spinlock);
        return EBADF;
    }
    int how = ft->ft_entries[fd]->ft_flags & O_ACCMODE;
    if ((how != O_RDONLY) && (how != O_RDWR)) {
        spinlock_release(&ft->ft_spinlock);
        return EBADF;
    }

	/* set up a uio with the buffer, its size, and the current offset */
    offset = ft->ft_entries[fd]->ft_pos;
	mk_useruio(&user_iov, &user_uio, buf, size, offset, UIO_READ);

	/* does the read */
    spinlock_release(&ft->ft_spinlock);
	result = VOP_READ(ft->ft_entries[fd]->ft_vnode, &user_uio);
	if (result) {
		return result;
	}

	/*
	 * The amount read is the size of the buffer originally, minus
	 * how much is left in it.
	 */
	*retval = size - user_uio.uio_resid;
    
    /* Advance file seek position. */
    spinlock_acquire(&ft->ft_spinlock);
    ft->ft_entries[fd]->ft_pos += *retval;

    spinlock_release(&ft->ft_spinlock);
	return 0;
}
Esempio n. 4
0
/*
 * sys___getcwd
 * Sets up the uio and call vfs_cwd.
 */
int
sys___getcwd(userptr_t buf, size_t buflen, int *retval)
{
    struct uio user_uio;
    struct iovec user_iov;
    int result;

    /* set up a uio with the buffer, its size, and the current offset */
    mk_useruio(&user_iov, &user_uio, buf, buflen, 0, UIO_READ);

    result = vfs_getcwd(&user_uio);
    *retval = result;

    return result;
}
Esempio n. 5
0
/*
 * sys___getcwd
 * 
 */
int
sys___getcwd(userptr_t buf, size_t buflen, int *retval)
{
	//get the uio construct way from sys_read
  kprintf(" doing getcwd");
	struct uio user_uio;
	struct iovec user_iov;
	int result;
  //consturct uio
	mk_useruio(&user_iov, &user_uio, buf, buflen, 0, UIO_READ);
  //use vfs_getcwd to do the work
	result = vfs_getcwd(&user_uio);
  //return what vfs_getcwd returned
	*retval = result;
	return result;
}
Esempio n. 6
0
/*
 * sys_getdirentry
 */
int
sys_getdirentry(int fd, userptr_t buf, size_t buflen, int *retval)
{
  struct filetable *file_table = curthread->t_filetable;
  spinlock_acquire(&file_table->filetable_lock);
  //kprintf("doing get dir");
  //check the fd is valid or not like we do in file_close
  if((fd > __OPEN_MAX) || (curthread->t_filetable->ft_entries[fd] == NULL) || (fd<0)){
    return EBADF;
  }

  //check the flag
  int how;
  how = file_table->ft_entries[fd]->flags & O_ACCMODE;
  if(how == O_WRONLY){
    spinlock_release(&file_table->filetable_lock);
    return EBADF;
  }

  //construct uio
  struct uio user_uio;
  struct iovec user_iov;
  int offset = file_table->ft_entries[fd]->pos;
  mk_useruio(&user_iov, &user_uio, buf, buflen, offset, UIO_READ);

  int result;
  struct vnode *vn;
  vn = file_table->ft_entries[fd]->file_vnode;
  //read the file into uio
  result = VOP_GETDIRENTRY(vn,&user_uio);
  //if fail
  if(result){
    spinlock_release(&file_table->filetable_lock);
    return result;
  }

  //on success upadate the offset
  file_table->ft_entries[fd]->pos = user_uio.uio_offset;
  //set retval to be the amount we read
  *retval = buflen - user_uio.uio_resid;
  spinlock_release(&file_table->filetable_lock);
  //kprintf("get dir done");
	return 0;
}