/*===========================================================================* * do_lseek * *===========================================================================*/ int do_lseek(void) { /* Perform the lseek(2) system call. */ off_t newpos = 0; int r; if ((r = actual_lseek(fp, job_m_in.m_lc_vfs_lseek.fd, job_m_in.m_lc_vfs_lseek.whence, job_m_in.m_lc_vfs_lseek.offset, &newpos)) != OK) return r; /* insert the new position into the output message */ job_m_out.m_vfs_lc_lseek.offset = newpos; return OK; }
/*===========================================================================* * 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; }
/*===========================================================================* * do_lseek * *===========================================================================*/ int do_lseek(message *m_out) { return actual_lseek(m_out, job_m_in.ls_fd, job_m_in.whence, (off_t) job_m_in.offset_lo); }