asst3-Virtual Memory Translation/kern/syscall/file_syscalls.c
static
int
sys_readwrite(int fd, userptr_t buf, size_t size, enum uio_rw rw,
	      int badaccmode, ssize_t *retval)
{
	struct openfile *file;
	bool locked;
	off_t pos;
	struct iovec iov;
	struct uio useruio;
	int result;

	/* better be a valid file descriptor */
	result = filetable_get(curproc->p_filetable, fd, &file);
	if (result) {
		return result;
	}

	/* Only lock the seek position if we're really using it. */
	locked = VOP_ISSEEKABLE(file->of_vnode);
	if (locked) {
		lock_acquire(file->of_offsetlock);
		pos = file->of_offset;
	}
	else {
		pos = 0;
	}

	if (file->of_accmode == badaccmode) {
		result = EBADF;
		goto fail;
	}

	/* set up a uio with the buffer, its size, and the current offset */
	uio_uinit(&iov, &useruio, buf, size, pos, rw);

	/* do the read or write */
	result = (rw == UIO_READ) ?
		VOP_READ(file->of_vnode, &useruio) :
		VOP_WRITE(file->of_vnode, &useruio);
	if (result) {
		goto fail;
	}

	if (locked) {
		/* set the offset to the updated offset in the uio */
		file->of_offset = useruio.uio_offset;
		lock_release(file->of_offsetlock);
	}

	filetable_put(curproc->p_filetable, fd, file);

	/*
	 * The amount read (or written) is the original buffer size,
	 * minus how much is left in it.
	 */
	*retval = size - useruio.uio_resid;

	return 0;

fail:
	if (locked) {
		lock_release(file->of_offsetlock);
	}
	filetable_put(curproc->p_filetable, fd, file);
	return result;
}
/*
 * Common logic for read and write.
 *
 * Look up the fd, then use VOP_READ or VOP_WRITE.
 */
Common logic for read and write.
Look up the fd, then use VOP_READ or VOP_WRITE.
Common logic for read and write . Look up the fd then use VOP_READ or VOP_WRITE .
static
int
sys_readwrite(int fd, userptr_t buf, size_t size, enum uio_rw rw,
	      int badaccmode, ssize_t *retval)
{
	struct openfile *file;
	bool locked;
	off_t pos;
	struct iovec iov;
	struct uio useruio;
	int result;
	result = filetable_get(curproc->p_filetable, fd, &file);
	if (result) {
		return result;
	}
	locked = VOP_ISSEEKABLE(file->of_vnode);
	if (locked) {
		lock_acquire(file->of_offsetlock);
		pos = file->of_offset;
	}
	else {
		pos = 0;
	}
	if (file->of_accmode == badaccmode) {
		result = EBADF;
		goto fail;
	}
	uio_uinit(&iov, &useruio, buf, size, pos, rw);
	result = (rw == UIO_READ) ?
		VOP_READ(file->of_vnode, &useruio) :
		VOP_WRITE(file->of_vnode, &useruio);
	if (result) {
		goto fail;
	}
	if (locked) {
		file->of_offset = useruio.uio_offset;
		lock_release(file->of_offsetlock);
	}
	filetable_put(curproc->p_filetable, fd, file);
	*retval = size - useruio.uio_resid;
	return 0;
fail:
	if (locked) {
		lock_release(file->of_offsetlock);
	}
	filetable_put(curproc->p_filetable, fd, file);
	return result;
}
static int sys_readwrite ( int fd , userptr_t buf , size_t size , enum uio_rw rw , int badaccmode , ssize_t * retval ) { struct openfile * file ; bool locked ; off_t pos ; struct iovec iov ; struct uio useruio ; int result ; result = filetable_get ( curproc -> p_filetable , fd , & file ) ; if ( result ) { return result ; } locked = VOP_ISSEEKABLE ( file -> of_vnode ) ; if ( locked ) { lock_acquire ( file -> of_offsetlock ) ; pos = file -> of_offset ; } else { pos = 0 ; } if ( file -> of_accmode == badaccmode ) { result = EBADF ; goto fail ; } uio_uinit ( & iov , & useruio , buf , size , pos , rw ) ; result = ( rw == UIO_READ ) ? VOP_READ ( file -> of_vnode , & useruio ) : VOP_WRITE ( file -> of_vnode , & useruio ) ; if ( result ) { goto fail ; } if ( locked ) { file -> of_offset = useruio . uio_offset ; lock_release ( file -> of_offsetlock ) ; } filetable_put ( curproc -> p_filetable , fd , file ) ; * retval = size - useruio . uio_resid ; return 0 ; fail : if ( locked ) { lock_release ( file -> of_offsetlock ) ; } filetable_put ( curproc -> p_filetable , fd , file ) ; return result ; }
Common logic for read and write.
Common logic for read and write .
/* better be a valid file descriptor */ /* Only lock the seek position if we're really using it. */ /* set up a uio with the buffer, its size, and the current offset */ /* do the read or write */ /* set the offset to the updated offset in the uio */ /*
	 * The amount read (or written) is the original buffer size,
	 * minus how much is left in it.
	 */