Beispiel #1
0
/*===========================================================================*
 *				do_vm_call				     *
 *===========================================================================*/
int do_vm_call(void)
{
/* A call that VM does to VFS.
 * We must reply with the fixed type VM_VFS_REPLY (and put our result info
 * in the rest of the message) so VM can tell the difference between a
 * request from VFS and a reply to this call.
 */
	int req = job_m_in.VFS_VMCALL_REQ;
	int req_fd = job_m_in.VFS_VMCALL_FD;
	u32_t req_id = job_m_in.VFS_VMCALL_REQID;
	endpoint_t ep = job_m_in.VFS_VMCALL_ENDPOINT;
	u64_t offset = job_m_in.VFS_VMCALL_OFFSET;
	u32_t length = job_m_in.VFS_VMCALL_LENGTH;
	int result = OK;
	int slot;
	struct fproc *rfp, *vmf;
	struct filp *f = NULL;
	int r;

	if(job_m_in.m_source != VM_PROC_NR)
		return ENOSYS;

	if(isokendpt(ep, &slot) != OK) rfp = NULL;
	else rfp = &fproc[slot];

	vmf = fproc_addr(VM_PROC_NR);
	assert(fp == vmf);
	assert(rfp != vmf);

	switch(req) {
		case VMVFSREQ_FDLOOKUP:
		{
			int procfd;

			/* Lookup fd in referenced process. */

			if(!rfp) {
				printf("VFS: why isn't ep %d here?!\n", ep);
				result = ESRCH;
				goto reqdone;
			}

			if((result = dupvm(rfp, req_fd, &procfd, &f)) != OK) {
#if 0   /* Noisy diagnostic for mmap() by ld.so */
				printf("vfs: dupvm failed\n");
#endif
				goto reqdone;
			}

			if(S_ISBLK(f->filp_vno->v_mode)) {
				assert(f->filp_vno->v_sdev != NO_DEV);
				job_m_out.VMV_DEV = f->filp_vno->v_sdev;
				job_m_out.VMV_INO = VMC_NO_INODE;
				job_m_out.VMV_SIZE_PAGES = LONG_MAX;
			} else {
				job_m_out.VMV_DEV = f->filp_vno->v_dev;
				job_m_out.VMV_INO = f->filp_vno->v_inode_nr;
				job_m_out.VMV_SIZE_PAGES =
					roundup(f->filp_vno->v_size,
						PAGE_SIZE)/PAGE_SIZE;
			}

			job_m_out.VMV_FD = procfd;

			result = OK;

			break;
		}
		case VMVFSREQ_FDCLOSE:
		{
			result = close_fd(fp, req_fd);
			if(result != OK) {
				printf("VFS: VM fd close for fd %d, %d (%d)\n",
					req_fd, fp->fp_endpoint, result);
			}
			break;
		}
		case VMVFSREQ_FDIO:
		{
			result = actual_lseek(fp, req_fd, SEEK_SET, offset,
				NULL);

			if(result == OK) {
				result = actual_read_write_peek(fp, PEEKING,
					req_fd, /* vir_bytes */ 0, length);
			}

			break;
		}
		default:
			panic("VFS: bad request code from VM\n");
			break;
	}

reqdone:
	if(f)
		unlock_filp(f);

	/* fp is VM still. */
	assert(fp == vmf);
	job_m_out.VMV_ENDPOINT = ep;
	job_m_out.VMV_RESULT = result;
	job_m_out.VMV_REQID = req_id;

	/* Reply asynchronously as VM may not be able to receive
	 * an ipc_sendnb() message.
	 */
	job_m_out.m_type = VM_VFS_REPLY;
	r = asynsend3(VM_PROC_NR, &job_m_out, 0);
	if(r != OK) printf("VFS: couldn't asynsend3() to VM\n");

	/* VFS does not reply any further */
	return SUSPEND;
}
Beispiel #2
0
/*===========================================================================*
 *				do_read_write_peek			     *
 *===========================================================================*/
int do_read_write_peek(int rw_flag, int io_fd, vir_bytes io_buf, size_t io_nbytes)
{
	return actual_read_write_peek(fp, rw_flag, io_fd, io_buf, io_nbytes);
}