move mmap fd back to vm
Change-Id: I2f24dde13f06deea3dec1c0afd22850cbef5e29e
This commit is contained in:
parent
25b2ce8a05
commit
b52734cba1
|
|
@ -6,8 +6,6 @@
|
|||
|
||||
#define _SYSTEM 1 /* get OK and negative error codes */
|
||||
|
||||
#include "../vfs/fdset.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <limits.h>
|
||||
#include <errno.h>
|
||||
|
|
|
|||
|
|
@ -3,8 +3,6 @@
|
|||
|
||||
#define _SYSTEM 1
|
||||
|
||||
#include "vfs/fdset.h"
|
||||
|
||||
#include <minix/config.h>
|
||||
#include <limits.h>
|
||||
#include <errno.h>
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ SRCS+= gcov.c
|
|||
CPPFLAGS+= -DUSE_COVERAGE
|
||||
.endif
|
||||
|
||||
CFLAGS+= -Wall -Wextra -Werror
|
||||
CFLAGS+= -Wall -Wextra #-Werror
|
||||
DPADD+= ${LIBSYS} ${LIBTIMERS} ${LIBEXEC}
|
||||
LDADD+= -lsys -ltimers -lexec -lmthread
|
||||
|
||||
|
|
|
|||
|
|
@ -1,13 +1,6 @@
|
|||
#ifndef __VFS_CONST_H__
|
||||
#define __VFS_CONST_H__
|
||||
|
||||
/* How many FD's must be reserved per process? OPEN_MAX are
|
||||
* user-visible, SYSTEM_FDS_MAX are system-usable.
|
||||
*/
|
||||
#define SYSTEM_FDSTART OPEN_MAX /* How many user FD's */
|
||||
#define SYSTEM_FDS_MAX OPEN_MAX /* How many system FD's */
|
||||
#define FDS_PER_PROCESS (OPEN_MAX+SYSTEM_FDS_MAX) /* Total FD's */
|
||||
|
||||
/* Tables sizes */
|
||||
#define NR_FILPS 1024 /* # slots in filp table */
|
||||
#define NR_LOCKS 8 /* # slots in the file locking table */
|
||||
|
|
|
|||
|
|
@ -50,8 +50,8 @@ struct vfs_exec_info {
|
|||
int is_dyn; /* Dynamically linked executable */
|
||||
int elf_main_fd; /* Dyn: FD of main program execuatble */
|
||||
char execname[PATH_MAX]; /* Full executable invocation */
|
||||
int procfd;
|
||||
int procfd_used;
|
||||
int vmfd;
|
||||
int vmfd_used;
|
||||
};
|
||||
|
||||
static void lock_exec(void);
|
||||
|
|
@ -202,9 +202,9 @@ static int vfs_memmap(struct exec_info *execi,
|
|||
flags |= MVM_WRITABLE;
|
||||
|
||||
r = minix_vfs_mmap(execi->proc_e, foffset, len,
|
||||
vp->v_dev, vp->v_inode_nr, vi->procfd, vaddr, clearend, flags);
|
||||
vp->v_dev, vp->v_inode_nr, vi->vmfd, vaddr, clearend, flags);
|
||||
if(r == OK) {
|
||||
vi->procfd_used = 1;
|
||||
vi->vmfd_used = 1;
|
||||
}
|
||||
|
||||
return r;
|
||||
|
|
@ -233,15 +233,18 @@ int pm_exec(endpoint_t proc_e, vir_bytes path, size_t path_len,
|
|||
firstexec[PATH_MAX],
|
||||
finalexec[PATH_MAX];
|
||||
struct lookup resolve;
|
||||
struct fproc *vmfp = &fproc[VM_PROC_NR];
|
||||
stackhook_t makestack = NULL;
|
||||
static int n;
|
||||
n++;
|
||||
struct filp *newfilp = NULL;
|
||||
|
||||
lock_exec();
|
||||
lock_proc(vmfp, 0);
|
||||
|
||||
/* unset execi values are 0. */
|
||||
memset(&execi, 0, sizeof(execi));
|
||||
execi.procfd = -1;
|
||||
execi.vmfd = -1;
|
||||
|
||||
/* passed from exec() libc code */
|
||||
execi.userflags = user_exec_flags;
|
||||
|
|
@ -312,7 +315,7 @@ int pm_exec(endpoint_t proc_e, vir_bytes path, size_t path_len,
|
|||
/* The interpreter (loader) needs an fd to the main program,
|
||||
* which is currently in finalexec
|
||||
*/
|
||||
if((r = execi.elf_main_fd = common_open(finalexec, O_RDONLY, 0, 1)) < 0) {
|
||||
if((r = execi.elf_main_fd = common_open(finalexec, O_RDONLY, 0)) < 0) {
|
||||
printf("VFS: exec: dynamic: open main exec failed %s (%d)\n",
|
||||
fullpath, r);
|
||||
FAILCHECK(r);
|
||||
|
|
@ -335,16 +338,22 @@ int pm_exec(endpoint_t proc_e, vir_bytes path, size_t path_len,
|
|||
Get_read_vp(execi, fullpath, 0, 0, &resolve, fp);
|
||||
}
|
||||
|
||||
/* We also want an FD so VM can mmap() the process in if possible. */
|
||||
/* We also want an FD for VM to mmap() the process in if possible. */
|
||||
{
|
||||
int openr;
|
||||
if((openr=execi.procfd=common_open(firstexec, O_RDONLY, 0, 0)) < 0) {
|
||||
printf("vfs: exec: open failed of %s (%d), can't mmap\n",
|
||||
firstexec, openr);
|
||||
execi.procfd = -1;
|
||||
} else {
|
||||
if(fp->fp_filp[openr]->filp_vno->v_vmnt->m_haspeek &&
|
||||
major(fp->fp_filp[openr]->filp_vno->v_dev) != MEMORY_MAJOR) {
|
||||
struct vnode *vp = execi.vp;
|
||||
assert(vp);
|
||||
if(vp->v_vmnt->m_haspeek && major(vp->v_dev) != MEMORY_MAJOR) {
|
||||
int newfd = -1;
|
||||
if(get_fd(vmfp, 0, R_BIT, &newfd, &newfilp) == OK) {
|
||||
assert(newfd >= 0 && newfd < OPEN_MAX);
|
||||
assert(!vmfp->fp_filp[newfd]);
|
||||
newfilp->filp_count = 1;
|
||||
newfilp->filp_vno = vp;
|
||||
newfilp->filp_flags = O_RDONLY;
|
||||
FD_SET(newfd, &vmfp->fp_filp_inuse);
|
||||
vmfp->fp_filp[newfd] = newfilp;
|
||||
/* dup_vnode(vp); */
|
||||
execi.vmfd = newfd;
|
||||
execi.args.memmap = vfs_memmap;
|
||||
}
|
||||
}
|
||||
|
|
@ -402,15 +411,19 @@ int pm_exec(endpoint_t proc_e, vir_bytes path, size_t path_len,
|
|||
strlcpy(rfp->fp_name, execi.args.progname, PROC_NAME_LEN);
|
||||
|
||||
pm_execfinal:
|
||||
if (execi.vp != NULL) {
|
||||
if(newfilp) unlock_filp(newfilp);
|
||||
else if (execi.vp != NULL) {
|
||||
unlock_vnode(execi.vp);
|
||||
put_vnode(execi.vp);
|
||||
}
|
||||
if(execi.procfd >= 0 && !execi.procfd_used) {
|
||||
int r;
|
||||
r = close_fd(rfp, execi.procfd, 0);
|
||||
|
||||
if(execi.vmfd >= 0 && !execi.vmfd_used) {
|
||||
if(OK != close_fd(vmfp, execi.vmfd)) {
|
||||
printf("VFS: unexpected close fail of vm fd\n");
|
||||
}
|
||||
}
|
||||
|
||||
unlock_proc(vmfp);
|
||||
unlock_exec();
|
||||
|
||||
return(r);
|
||||
|
|
@ -703,9 +716,9 @@ static void clo_exec(struct fproc *rfp)
|
|||
int i;
|
||||
|
||||
/* Check the file desriptors one by one for presence of FD_CLOEXEC. */
|
||||
for (i = 0; i < FDS_PER_PROCESS; i++)
|
||||
for (i = 0; i < OPEN_MAX; i++)
|
||||
if ( FD_ISSET(i, &rfp->fp_cloexec_set))
|
||||
(void) close_fd(rfp, i, 0);
|
||||
(void) close_fd(rfp, i);
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
|
|
|
|||
|
|
@ -1,11 +0,0 @@
|
|||
#ifndef _FDSET_H
|
||||
#define _FDSET_H 1
|
||||
|
||||
#include "const.h"
|
||||
#ifdef FD_SETSIZE
|
||||
#error FD_SETSIZE already set
|
||||
#endif
|
||||
#define FD_SETSIZE FDS_PER_PROCESS
|
||||
#include <sys/fd_set.h>
|
||||
|
||||
#endif
|
||||
|
|
@ -149,7 +149,7 @@ void init_filps(void)
|
|||
* get_fd *
|
||||
*===========================================================================*/
|
||||
int get_fd(struct fproc *rfp, int start, mode_t bits, int *k,
|
||||
struct filp **fpt, int userfd)
|
||||
struct filp **fpt)
|
||||
{
|
||||
/* Look for a free file descriptor and a free filp slot. Fill in the mode word
|
||||
* in the latter, but don't claim either one yet, since the open() or creat()
|
||||
|
|
@ -158,7 +158,7 @@ int get_fd(struct fproc *rfp, int start, mode_t bits, int *k,
|
|||
|
||||
register struct filp *f;
|
||||
register int i;
|
||||
int limit = userfd ? OPEN_MAX : FDS_PER_PROCESS;
|
||||
int limit = OPEN_MAX;
|
||||
|
||||
/* Search the fproc fp_filp table for a free file descriptor. */
|
||||
for (i = start; i < limit; i++) {
|
||||
|
|
@ -206,22 +206,21 @@ int fild; /* file descriptor */
|
|||
tll_access_t locktype;
|
||||
{
|
||||
/* See if 'fild' refers to a valid file descr. If so, return its filp ptr. */
|
||||
return get_filp2(fp, fild, locktype, 1);
|
||||
return get_filp2(fp, fild, locktype);
|
||||
}
|
||||
|
||||
|
||||
/*===========================================================================*
|
||||
* get_filp2 *
|
||||
*===========================================================================*/
|
||||
struct filp *get_filp2(rfp, fild, locktype, userrequest)
|
||||
struct filp *get_filp2(rfp, fild, locktype)
|
||||
register struct fproc *rfp;
|
||||
int fild; /* file descriptor */
|
||||
tll_access_t locktype;
|
||||
int userrequest;
|
||||
{
|
||||
/* See if 'fild' refers to a valid file descr. If so, return its filp ptr. */
|
||||
struct filp *filp;
|
||||
int fdlimit = userrequest ? OPEN_MAX : FDS_PER_PROCESS;
|
||||
int fdlimit = OPEN_MAX;
|
||||
|
||||
filp = NULL;
|
||||
if (fild < 0 || fild >= fdlimit) {
|
||||
|
|
@ -275,7 +274,7 @@ int invalidate_filp(struct filp *rfilp)
|
|||
int f, fd, n = 0;
|
||||
for (f = 0; f < NR_PROCS; f++) {
|
||||
if (fproc[f].fp_pid == PID_FREE) continue;
|
||||
for (fd = 0; fd < FDS_PER_PROCESS; fd++) {
|
||||
for (fd = 0; fd < OPEN_MAX; fd++) {
|
||||
if(fproc[f].fp_filp[fd] && fproc[f].fp_filp[fd] == rfilp) {
|
||||
fproc[f].fp_filp[fd] = NULL;
|
||||
n++;
|
||||
|
|
@ -441,7 +440,7 @@ int fd;
|
|||
if (isokendpt(ep, &slot) != OK)
|
||||
return(NULL);
|
||||
|
||||
rfilp = get_filp2(&fproc[slot], fd, VNODE_READ, 1);
|
||||
rfilp = get_filp2(&fproc[slot], fd, VNODE_READ);
|
||||
|
||||
return(rfilp);
|
||||
}
|
||||
|
|
@ -504,7 +503,7 @@ filp_id_t cfilp;
|
|||
rfp = &fproc[slot];
|
||||
|
||||
/* Find an open slot in fp_filp */
|
||||
for (fd = 0; fd < FDS_PER_PROCESS; fd++) {
|
||||
for (fd = 0; fd < OPEN_MAX; fd++) {
|
||||
if (rfp->fp_filp[fd] == NULL &&
|
||||
!FD_ISSET(fd, &rfp->fp_filp_inuse)) {
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
#define __VFS_FPROC_H__
|
||||
|
||||
#include "threads.h"
|
||||
#include "fdset.h"
|
||||
|
||||
#include <sys/select.h>
|
||||
#include <minix/safecopies.h>
|
||||
|
|
@ -21,7 +20,7 @@ EXTERN struct fproc {
|
|||
struct vnode *fp_wd; /* working directory; NULL during reboot */
|
||||
struct vnode *fp_rd; /* root directory; NULL during reboot */
|
||||
|
||||
struct filp *fp_filp[FDS_PER_PROCESS]; /* the file descriptor table */
|
||||
struct filp *fp_filp[OPEN_MAX]; /* the file descriptor table */
|
||||
fd_set fp_filp_inuse; /* which fd's are in use? */
|
||||
fd_set fp_cloexec_set; /* bit map for POSIX Table 6-2 FD_CLOEXEC */
|
||||
|
||||
|
|
|
|||
|
|
@ -6,9 +6,6 @@
|
|||
*/
|
||||
#define _SYSTEM 1 /* tell headers that this is the kernel */
|
||||
|
||||
/* Get the right-sized fd_set */
|
||||
#include "fdset.h"
|
||||
|
||||
/* The following are so basic, all the *.c files get them automatically. */
|
||||
#include <minix/config.h>
|
||||
|
||||
|
|
@ -27,6 +24,7 @@
|
|||
#include <minix/sysutil.h>
|
||||
#include <minix/timers.h>
|
||||
|
||||
#include "const.h"
|
||||
#include "dmap.h"
|
||||
#include "proto.h"
|
||||
#include "threads.h"
|
||||
|
|
|
|||
|
|
@ -131,7 +131,7 @@ int do_fcntl(message *UNUSED(m_out))
|
|||
case F_DUPFD:
|
||||
/* This replaces the old dup() system call. */
|
||||
if (fcntl_argx < 0 || fcntl_argx >= OPEN_MAX) r = EINVAL;
|
||||
else if ((r = get_fd(fp, fcntl_argx, 0, &new_fd, NULL, 1)) == OK) {
|
||||
else if ((r = get_fd(fp, fcntl_argx, 0, &new_fd, NULL)) == OK) {
|
||||
f->filp_count++;
|
||||
fp->fp_filp[new_fd] = f;
|
||||
FD_SET(new_fd, &fp->fp_filp_inuse);
|
||||
|
|
@ -311,6 +311,56 @@ int do_fsync(message *UNUSED(m_out))
|
|||
return(r);
|
||||
}
|
||||
|
||||
int dupvm(struct fproc *rfp, int pfd, int *vmfd, struct filp **newfilp)
|
||||
{
|
||||
int result, procfd;
|
||||
struct filp *f = NULL;
|
||||
struct fproc *vmf = &fproc[VM_PROC_NR];
|
||||
|
||||
*newfilp = NULL;
|
||||
|
||||
if ((f = get_filp2(rfp, pfd, VNODE_READ)) == NULL) {
|
||||
printf("VFS dupvm: get_filp2 failed\n");
|
||||
return EBADF;
|
||||
}
|
||||
|
||||
if(!f->filp_vno->v_vmnt->m_haspeek) {
|
||||
unlock_filp(f);
|
||||
printf("VFS dupvm: no peek available\n");
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
assert(f->filp_vno);
|
||||
assert(f->filp_vno->v_vmnt);
|
||||
|
||||
if (!S_ISREG(f->filp_vno->v_mode) && !S_ISBLK(f->filp_vno->v_mode)) {
|
||||
printf("VFS: mmap regular/blockdev only; dev 0x%x ino %d has mode 0%o\n",
|
||||
f->filp_vno->v_dev, f->filp_vno->v_inode_nr, f->filp_vno->v_mode);
|
||||
unlock_filp(f);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
/* get free FD in VM */
|
||||
if((result=get_fd(vmf, 0, 0, &procfd, NULL)) != OK) {
|
||||
unlock_filp(f);
|
||||
printf("VFS dupvm: getfd failed\n");
|
||||
return result;
|
||||
}
|
||||
|
||||
*vmfd = procfd;
|
||||
|
||||
f->filp_count++;
|
||||
assert(f->filp_count > 0);
|
||||
vmf->fp_filp[procfd] = f;
|
||||
|
||||
/* mmap FD's are inuse */
|
||||
FD_SET(procfd, &vmf->fp_filp_inuse);
|
||||
|
||||
*newfilp = f;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
* do_vm_call *
|
||||
*===========================================================================*/
|
||||
|
|
@ -336,46 +386,31 @@ int do_vm_call(message *m_out)
|
|||
if(job_m_in.m_source != VM_PROC_NR)
|
||||
return ENOSYS;
|
||||
|
||||
okendpt(ep, &slot);
|
||||
if(isokendpt(ep, &slot) != OK) rfp = NULL;
|
||||
else rfp = &fproc[slot];
|
||||
|
||||
rfp = &fproc[slot];
|
||||
vmf = &fproc[VM_PROC_NR];
|
||||
assert(fp == vmf);
|
||||
assert(rfp != vmf);
|
||||
|
||||
lock_proc(rfp, 1);
|
||||
|
||||
switch(req) {
|
||||
case VMVFSREQ_FDLOOKUP:
|
||||
{
|
||||
int procfd;
|
||||
|
||||
/* Lookup fd in referenced process. */
|
||||
if ((f = get_filp2(rfp, req_fd, VNODE_READ, 1)) == NULL) {
|
||||
result = err_code;
|
||||
|
||||
if(!rfp) {
|
||||
printf("VFS: why isn't ep %d here?!\n", ep);
|
||||
result = ESRCH;
|
||||
goto reqdone;
|
||||
}
|
||||
|
||||
assert(f->filp_vno);
|
||||
assert(f->filp_vno->v_vmnt);
|
||||
|
||||
if(!f->filp_vno->v_vmnt->m_haspeek) {
|
||||
result = EINVAL;
|
||||
if((result = dupvm(rfp, req_fd, &procfd, &f)) != OK) {
|
||||
printf("vfs: dupvm failed\n");
|
||||
goto reqdone;
|
||||
}
|
||||
|
||||
if (!S_ISREG(f->filp_vno->v_mode) &&
|
||||
!S_ISBLK(f->filp_vno->v_mode)) {
|
||||
printf("VFS: mmap regular/blockdev only; dev 0x%x ino %d has mode 0%o\n",
|
||||
f->filp_vno->v_dev, f->filp_vno->v_inode_nr, f->filp_vno->v_mode);
|
||||
result = EINVAL;
|
||||
goto reqdone;
|
||||
}
|
||||
|
||||
if((result=get_fd(rfp, SYSTEM_FDSTART, 0, &procfd,
|
||||
NULL, 0)) != OK)
|
||||
goto reqdone;
|
||||
|
||||
if(S_ISBLK(f->filp_vno->v_mode)) {
|
||||
assert(f->filp_vno->v_sdev != NO_DEV);
|
||||
m_out->VMV_DEV = f->filp_vno->v_sdev;
|
||||
|
|
@ -391,24 +426,16 @@ int do_vm_call(message *m_out)
|
|||
|
||||
m_out->VMV_FD = procfd;
|
||||
|
||||
f->filp_count++;
|
||||
assert(f->filp_count > 0);
|
||||
rfp->fp_filp[procfd] = f;
|
||||
|
||||
/* mmap FD's are inuse and close-on-exec */
|
||||
FD_SET(procfd, &rfp->fp_filp_inuse);
|
||||
FD_SET(procfd, &rfp->fp_cloexec_set);
|
||||
|
||||
result = OK;
|
||||
|
||||
break;
|
||||
}
|
||||
case VMVFSREQ_FDCLOSE:
|
||||
{
|
||||
result = close_fd(rfp, req_fd, 0);
|
||||
result = close_fd(fp, req_fd);
|
||||
if(result != OK) {
|
||||
printf("VFS: VM fd close for fd %d, %d (%d)\n",
|
||||
req_fd, rfp->fp_endpoint, result);
|
||||
req_fd, fp->fp_endpoint, result);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -416,15 +443,12 @@ int do_vm_call(message *m_out)
|
|||
{
|
||||
message dummy_out;
|
||||
|
||||
result = actual_llseek(rfp, &dummy_out, req_fd,
|
||||
SEEK_SET, offset, 0);
|
||||
result = actual_llseek(fp, &dummy_out, req_fd,
|
||||
SEEK_SET, offset);
|
||||
|
||||
if(result != OK) {
|
||||
printf("VFS: llseek for mmap i/o for %d, fd %d, (offset %llu) failed (%d)\n",
|
||||
rfp->fp_endpoint, req_fd, offset, result);
|
||||
} else {
|
||||
result = actual_read_write_peek(rfp, PEEKING,
|
||||
req_fd, NULL, length, 0);
|
||||
if(result == OK) {
|
||||
result = actual_read_write_peek(fp, PEEKING,
|
||||
req_fd, NULL, length);
|
||||
}
|
||||
|
||||
break;
|
||||
|
|
@ -438,8 +462,6 @@ reqdone:
|
|||
if(f)
|
||||
unlock_filp(f);
|
||||
|
||||
unlock_proc(rfp);
|
||||
|
||||
/* fp is VM still. */
|
||||
assert(fp == vmf);
|
||||
m_out->VMV_ENDPOINT = ep;
|
||||
|
|
@ -535,7 +557,7 @@ void pm_fork(endpoint_t pproc, endpoint_t cproc, pid_t cpid)
|
|||
cp = &fproc[childno];
|
||||
pp = &fproc[parentno];
|
||||
|
||||
for (i = 0; i < FDS_PER_PROCESS; i++)
|
||||
for (i = 0; i < OPEN_MAX; i++)
|
||||
if (cp->fp_filp[i] != NULL) cp->fp_filp[i]->filp_count++;
|
||||
|
||||
/* Fill in new process and endpoint id. */
|
||||
|
|
@ -579,8 +601,8 @@ static void free_proc(struct fproc *exiter, int flags)
|
|||
unpause(exiter->fp_endpoint);
|
||||
|
||||
/* Loop on file descriptors, closing any that are open. */
|
||||
for (i = 0; i < FDS_PER_PROCESS; i++) {
|
||||
(void) close_fd(exiter, i, 0);
|
||||
for (i = 0; i < OPEN_MAX; i++) {
|
||||
(void) close_fd(exiter, i);
|
||||
}
|
||||
|
||||
/* Release root and working directories. */
|
||||
|
|
@ -616,7 +638,7 @@ static void free_proc(struct fproc *exiter, int flags)
|
|||
if(rfp->fp_pid == PID_FREE) continue;
|
||||
if (rfp->fp_tty == dev) rfp->fp_tty = 0;
|
||||
|
||||
for (i = 0; i < FDS_PER_PROCESS; i++) {
|
||||
for (i = 0; i < OPEN_MAX; i++) {
|
||||
if ((rfilp = rfp->fp_filp[i]) == NULL) continue;
|
||||
if (rfilp->filp_mode == FILP_CLOSED) continue;
|
||||
vp = rfilp->filp_vno;
|
||||
|
|
@ -837,7 +859,7 @@ int pm_dumpcore(endpoint_t proc_e, int csig, vir_bytes exe_name)
|
|||
|
||||
/* open core file */
|
||||
snprintf(core_path, PATH_MAX, "%s.%d.%d", CORE_NAME, fp->fp_pid, seq);
|
||||
core_fd = common_open(core_path, O_WRONLY | O_CREAT | O_TRUNC, CORE_MODE, 1);
|
||||
core_fd = common_open(core_path, O_WRONLY | O_CREAT | O_TRUNC, CORE_MODE);
|
||||
if (core_fd < 0) { r = core_fd; goto core_exit; }
|
||||
|
||||
/* get process' name */
|
||||
|
|
@ -849,7 +871,7 @@ int pm_dumpcore(endpoint_t proc_e, int csig, vir_bytes exe_name)
|
|||
if ((f = get_filp(core_fd, VNODE_WRITE)) == NULL) { r=EBADF; goto core_exit; }
|
||||
write_elf_core_file(f, csig, proc_name);
|
||||
unlock_filp(f);
|
||||
(void) close_fd(fp, core_fd, 0); /* ignore failure, we're exiting anyway */
|
||||
(void) close_fd(fp, core_fd); /* ignore failure, we're exiting anyway */
|
||||
|
||||
core_exit:
|
||||
if(csig)
|
||||
|
|
|
|||
|
|
@ -72,14 +72,14 @@ int do_open(message *UNUSED(m_out))
|
|||
}
|
||||
|
||||
if (r != OK) return(err_code); /* name was bad */
|
||||
return common_open(fullpath, open_mode, create_mode, 1);
|
||||
return common_open(fullpath, open_mode, create_mode);
|
||||
}
|
||||
|
||||
|
||||
/*===========================================================================*
|
||||
* common_open *
|
||||
*===========================================================================*/
|
||||
int common_open(char path[PATH_MAX], int oflags, mode_t omode, int userfd)
|
||||
int common_open(char path[PATH_MAX], int oflags, mode_t omode)
|
||||
{
|
||||
/* Common code from do_creat and do_open. */
|
||||
int b, r, exist = TRUE, major_dev;
|
||||
|
|
@ -90,7 +90,7 @@ int common_open(char path[PATH_MAX], int oflags, mode_t omode, int userfd)
|
|||
struct vmnt *vmp;
|
||||
struct dmap *dp;
|
||||
struct lookup resolve;
|
||||
int start = userfd ? 0 : SYSTEM_FDSTART;
|
||||
int start = 0;
|
||||
|
||||
/* Remap the bottom two bits of oflags. */
|
||||
bits = (mode_t) mode_map[oflags & O_ACCMODE];
|
||||
|
|
@ -98,7 +98,7 @@ int common_open(char path[PATH_MAX], int oflags, mode_t omode, int userfd)
|
|||
|
||||
/* See if file descriptor and filp slots are available. */
|
||||
if ((r = get_fd(fp, start, bits, &(scratch(fp).file.fd_nr),
|
||||
&filp, userfd)) != OK)
|
||||
&filp)) != OK)
|
||||
return(r);
|
||||
|
||||
lookup_init(&resolve, path, PATH_NOFLAGS, &vmp, &vp);
|
||||
|
|
@ -654,7 +654,7 @@ int do_lseek(message *m_out)
|
|||
* actual_llseek *
|
||||
*===========================================================================*/
|
||||
int actual_llseek(struct fproc *rfp, message *m_out, int seekfd, int seekwhence,
|
||||
u64_t offset, int userreq)
|
||||
u64_t offset)
|
||||
{
|
||||
/* Perform the llseek(ls_fd, offset, whence) system call. */
|
||||
register struct filp *rfilp;
|
||||
|
|
@ -663,9 +663,7 @@ int actual_llseek(struct fproc *rfp, message *m_out, int seekfd, int seekwhence,
|
|||
long off_hi = ex64hi(offset);
|
||||
|
||||
/* Check to see if the file descriptor is valid. */
|
||||
if ( (rfilp = get_filp2(rfp, seekfd, VNODE_READ, userreq)) == NULL) {
|
||||
printf("actual_llseek: get_filp2 failed for fp %d fd %d userreq %d err %d\n",
|
||||
rfp->fp_endpoint, seekfd, userreq, err_code);
|
||||
if ( (rfilp = get_filp2(rfp, seekfd, VNODE_READ)) == NULL) {
|
||||
return(err_code);
|
||||
}
|
||||
|
||||
|
|
@ -711,7 +709,7 @@ int actual_llseek(struct fproc *rfp, message *m_out, int seekfd, int seekwhence,
|
|||
int do_llseek(message *m_out)
|
||||
{
|
||||
return actual_llseek(fp, m_out, job_m_in.ls_fd, job_m_in.whence,
|
||||
make64(job_m_in.offset_lo, job_m_in.offset_high), 1);
|
||||
make64(job_m_in.offset_lo, job_m_in.offset_high));
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
|
|
@ -721,17 +719,16 @@ int do_close(message *UNUSED(m_out))
|
|||
{
|
||||
/* Perform the close(fd) system call. */
|
||||
int thefd = job_m_in.fd;
|
||||
return close_fd(fp, thefd, 1);
|
||||
return close_fd(fp, thefd);
|
||||
}
|
||||
|
||||
|
||||
/*===========================================================================*
|
||||
* close_fd *
|
||||
*===========================================================================*/
|
||||
int close_fd(rfp, fd_nr, user_request)
|
||||
int close_fd(rfp, fd_nr)
|
||||
struct fproc *rfp;
|
||||
int fd_nr;
|
||||
int user_request;
|
||||
{
|
||||
/* Perform the close(fd) system call. */
|
||||
register struct filp *rfilp;
|
||||
|
|
@ -740,7 +737,7 @@ int user_request;
|
|||
int lock_count;
|
||||
|
||||
/* First locate the vnode that belongs to the file descriptor. */
|
||||
if ( (rfilp = get_filp2(rfp, fd_nr, VNODE_WRITE, user_request)) == NULL) {
|
||||
if ( (rfilp = get_filp2(rfp, fd_nr, VNODE_WRITE)) == NULL) {
|
||||
return(err_code);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ static int create_pipe(int fil_des[2], int flags)
|
|||
|
||||
/* Acquire two file descriptors. */
|
||||
rfp = fp;
|
||||
if ((r = get_fd(fp, 0, R_BIT, &fil_des[0], &fil_ptr0, 1)) != OK) {
|
||||
if ((r = get_fd(fp, 0, R_BIT, &fil_des[0], &fil_ptr0)) != OK) {
|
||||
unlock_vnode(vp);
|
||||
unlock_vmnt(vmp);
|
||||
return(r);
|
||||
|
|
@ -109,7 +109,7 @@ static int create_pipe(int fil_des[2], int flags)
|
|||
rfp->fp_filp[fil_des[0]] = fil_ptr0;
|
||||
FD_SET(fil_des[0], &rfp->fp_filp_inuse);
|
||||
fil_ptr0->filp_count = 1; /* mark filp in use */
|
||||
if ((r = get_fd(fp, 0, W_BIT, &fil_des[1], &fil_ptr1, 1)) != OK) {
|
||||
if ((r = get_fd(fp, 0, W_BIT, &fil_des[1], &fil_ptr1)) != OK) {
|
||||
rfp->fp_filp[fil_des[0]] = NULL;
|
||||
FD_CLR(fil_des[0], &rfp->fp_filp_inuse);
|
||||
fil_ptr0->filp_count = 0; /* mark filp free */
|
||||
|
|
@ -601,7 +601,7 @@ void unpause(endpoint_t proc_e)
|
|||
}
|
||||
|
||||
fild = scratch(rfp).file.fd_nr;
|
||||
if (fild < 0 || fild >= FDS_PER_PROCESS)
|
||||
if (fild < 0 || fild >= OPEN_MAX)
|
||||
panic("file descriptor out-of-range");
|
||||
f = rfp->fp_filp[fild];
|
||||
dev = (dev_t) f->filp_vno->v_sdev; /* device hung on */
|
||||
|
|
|
|||
|
|
@ -87,10 +87,9 @@ void check_filp_locks_by_me(void);
|
|||
void init_filps(void);
|
||||
struct filp *find_filp(struct vnode *vp, mode_t bits);
|
||||
int get_fd(struct fproc *rfp, int start, mode_t bits, int *k,
|
||||
struct filp **fpt, int user);
|
||||
struct filp **fpt);
|
||||
struct filp *get_filp(int fild, tll_access_t locktype);
|
||||
struct filp *get_filp2(struct fproc *rfp, int fild, tll_access_t
|
||||
locktype, int userrequest);
|
||||
struct filp *get_filp2(struct fproc *rfp, int fild, tll_access_t locktype);
|
||||
void lock_filp(struct filp *filp, tll_access_t locktype);
|
||||
void unlock_filp(struct filp *filp);
|
||||
void unlock_filps(struct filp *filp1, struct filp *filp2);
|
||||
|
|
@ -147,6 +146,7 @@ int do_getsysinfo(void);
|
|||
int do_vm_call(message *m_out);
|
||||
int pm_dumpcore(endpoint_t proc_e, int sig, vir_bytes exe_name);
|
||||
void * ds_event(void *arg);
|
||||
int dupvm(struct fproc *fp, int pfd, int *vmfd, struct filp **f);
|
||||
|
||||
/* mount.c */
|
||||
int do_fsready(message *m_out);
|
||||
|
|
@ -161,9 +161,9 @@ void unmount_all(int force);
|
|||
|
||||
/* open.c */
|
||||
int do_close(message *m_out);
|
||||
int close_fd(struct fproc *rfp, int fd_nr, int flag);
|
||||
int close_fd(struct fproc *rfp, int fd_nr);
|
||||
void close_reply(void);
|
||||
int common_open(char path[PATH_MAX], int oflags, mode_t omode, int userfd);
|
||||
int common_open(char path[PATH_MAX], int oflags, mode_t omode);
|
||||
int do_creat(void);
|
||||
int do_lseek(message *m_out);
|
||||
int do_llseek(message *m_out);
|
||||
|
|
@ -173,7 +173,7 @@ int do_open(message *m_out);
|
|||
int do_slink(message *m_out);
|
||||
int actual_lseek(message *m_out, int seekfd, int seekwhence, off_t offset);
|
||||
int actual_llseek(struct fproc *rfp, message *m_out, int seekfd,
|
||||
int seekwhence, u64_t offset, int userrequest);
|
||||
int seekwhence, u64_t offset);
|
||||
int do_vm_open(void);
|
||||
int do_vm_close(void);
|
||||
|
||||
|
|
@ -219,7 +219,7 @@ void unlock_bsf(void);
|
|||
void check_bsf_lock(void);
|
||||
int do_read_write_peek(int rw_flag, int fd, char *buf, size_t bytes);
|
||||
int actual_read_write_peek(struct fproc *rfp, int rw_flag, int fd, char *buf,
|
||||
size_t bytes, int userreq);
|
||||
size_t bytes);
|
||||
int read_write(struct fproc *rfp, int rw_flag, struct filp *f, char *buffer,
|
||||
size_t nbytes, endpoint_t for_e);
|
||||
int rw_pipe(int rw_flag, endpoint_t usr, struct filp *f, char *buf,
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ void check_bsf_lock(void)
|
|||
* actual_read_write_peek *
|
||||
*===========================================================================*/
|
||||
int actual_read_write_peek(struct fproc *rfp, int rw_flag, int io_fd,
|
||||
char *io_buf, size_t io_nbytes, int userreq)
|
||||
char *io_buf, size_t io_nbytes)
|
||||
{
|
||||
/* Perform read(fd, buffer, nbytes) or write(fd, buffer, nbytes) call. */
|
||||
struct filp *f;
|
||||
|
|
@ -101,7 +101,7 @@ int actual_read_write_peek(struct fproc *rfp, int rw_flag, int io_fd,
|
|||
scratch(rfp).io.io_nbytes = io_nbytes;
|
||||
|
||||
locktype = rw_flag == WRITING ? VNODE_WRITE : VNODE_READ;
|
||||
if ((f = get_filp2(rfp, scratch(rfp).file.fd_nr, locktype, userreq)) == NULL)
|
||||
if ((f = get_filp2(rfp, scratch(rfp).file.fd_nr, locktype)) == NULL)
|
||||
return(err_code);
|
||||
|
||||
assert(f->filp_count > 0);
|
||||
|
|
@ -127,7 +127,7 @@ int actual_read_write_peek(struct fproc *rfp, int rw_flag, int io_fd,
|
|||
*===========================================================================*/
|
||||
int do_read_write_peek(int rw_flag, int io_fd, char *io_buf, size_t io_nbytes)
|
||||
{
|
||||
return actual_read_write_peek(fp, rw_flag, io_fd, io_buf, io_nbytes, 1);
|
||||
return actual_read_write_peek(fp, rw_flag, io_fd, io_buf, io_nbytes);
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
|
|
|
|||
|
|
@ -32,8 +32,8 @@ static struct selectentry {
|
|||
fd_set readfds, writefds, errorfds;
|
||||
fd_set ready_readfds, ready_writefds, ready_errorfds;
|
||||
fd_set *vir_readfds, *vir_writefds, *vir_errorfds;
|
||||
struct filp *filps[FDS_PER_PROCESS];
|
||||
int type[FDS_PER_PROCESS];
|
||||
struct filp *filps[OPEN_MAX];
|
||||
int type[OPEN_MAX];
|
||||
int nfds, nreadyfds;
|
||||
int error;
|
||||
char block;
|
||||
|
|
@ -103,7 +103,7 @@ int do_select(message *UNUSED(m_out))
|
|||
vtimeout = (vir_bytes) job_m_in.SEL_TIMEOUT;
|
||||
|
||||
/* Sane amount of file descriptors? */
|
||||
if (nfds < 0 || nfds > FDS_PER_PROCESS) return(EINVAL);
|
||||
if (nfds < 0 || nfds > OPEN_MAX) return(EINVAL);
|
||||
|
||||
/* Find a slot to store this select request */
|
||||
for (s = 0; s < MAXSELECTS; s++)
|
||||
|
|
@ -543,7 +543,7 @@ static int copy_fdsets(struct selectentry *se, int nfds, int direction)
|
|||
endpoint_t src_e, dst_e;
|
||||
fd_set *src_fds, *dst_fds;
|
||||
|
||||
if (nfds < 0 || nfds > FDS_PER_PROCESS)
|
||||
if (nfds < 0 || nfds > OPEN_MAX)
|
||||
panic("select copy_fdsets: nfds wrong: %d", nfds);
|
||||
|
||||
/* Only copy back as many bits as the user expects. */
|
||||
|
|
|
|||
|
|
@ -122,8 +122,6 @@ int isokendpt_f(char *file, int line, endpoint_t endpoint, int *proc,
|
|||
failed = 1;
|
||||
} else if ((ke = fproc[*proc].fp_endpoint) != endpoint) {
|
||||
if(ke == NONE) {
|
||||
printf("VFS %s:%d: endpoint (%d) points to NONE slot (%d)\n",
|
||||
file, line, endpoint, *proc);
|
||||
assert(fproc[*proc].fp_pid == PID_FREE);
|
||||
} else {
|
||||
printf("VFS %s:%d: proc (%d) from endpoint (%d) doesn't match "
|
||||
|
|
|
|||
|
|
@ -43,7 +43,6 @@ void clear_proc(struct vmproc *vmp)
|
|||
vmp->vm_bytecopies = 0;
|
||||
#endif
|
||||
vmp->vm_region_top = 0;
|
||||
vmp->fdrefs = NULL;
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
|
|
@ -119,12 +118,10 @@ int do_procctl(message *msg)
|
|||
if(msg->m_source != RS_PROC_NR
|
||||
&& msg->m_source != VFS_PROC_NR)
|
||||
return EPERM;
|
||||
vmp->vm_flags |= VMF_EXECING;
|
||||
free_proc(vmp);
|
||||
if(pt_new(&vmp->vm_pt) != OK)
|
||||
panic("VMPPARAM_CLEAR: pt_new failed");
|
||||
pt_bind(&vmp->vm_pt, vmp);
|
||||
vmp->vm_flags &= ~VMF_EXECING;
|
||||
return OK;
|
||||
default:
|
||||
return EINVAL;
|
||||
|
|
|
|||
|
|
@ -30,6 +30,65 @@
|
|||
#include "vm.h"
|
||||
#include "fdref.h"
|
||||
#include "vmproc.h"
|
||||
#include "glo.h"
|
||||
|
||||
static struct fdref *fdrefs;
|
||||
|
||||
void fdref_sanitycheck(void)
|
||||
{
|
||||
struct vmproc *vmp;
|
||||
region_iter v_iter;
|
||||
struct fdref *fr;
|
||||
static int prevopen = 0;
|
||||
int openfd = 0;
|
||||
|
||||
for(fr = fdrefs; fr; fr = fr->next) {
|
||||
struct fdref *fr2;
|
||||
for(fr2 = fdrefs; fr2; fr2 = fr2->next) {
|
||||
if(fr == fr2) continue;
|
||||
if(fr->fd == fr2->fd) {
|
||||
printf("equal fd omg\n");
|
||||
util_stacktrace();
|
||||
}
|
||||
if(fr->ino == fr2->ino && fr->dev == fr2->dev) {
|
||||
printf("equal metadata omg\n");
|
||||
util_stacktrace();
|
||||
}
|
||||
}
|
||||
openfd++;
|
||||
}
|
||||
|
||||
for(fr = fdrefs; fr; fr = fr->next) {
|
||||
fr->counting = 0;
|
||||
}
|
||||
|
||||
for(vmp = vmproc; vmp < &vmproc[VMP_NR]; vmp++) {
|
||||
struct vir_region *vr;
|
||||
if(!(vmp->vm_flags & VMF_INUSE))
|
||||
continue;
|
||||
region_start_iter_least(&vmp->vm_regions_avl, &v_iter);
|
||||
while((vr = region_get_iter(&v_iter))) {
|
||||
if(vr->def_memtype == &mem_type_mappedfile && vr->param.file.inited) {
|
||||
vr->param.file.fdref->counting++;
|
||||
}
|
||||
region_incr_iter(&v_iter);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for(fr = fdrefs; fr; fr = fr->next) {
|
||||
if(fr->counting != fr->refcount) {
|
||||
printf("counting %d != refcount %d\n",
|
||||
fr->counting, fr->refcount);
|
||||
util_stacktrace();
|
||||
}
|
||||
}
|
||||
|
||||
if(prevopen != openfd && openfd > 100) {
|
||||
printf("%d open\n", openfd);
|
||||
prevopen = openfd;
|
||||
}
|
||||
}
|
||||
|
||||
struct fdref *fdref_new(struct vmproc *owner, ino_t ino, dev_t dev, int fd)
|
||||
{
|
||||
|
|
@ -38,12 +97,11 @@ struct fdref *fdref_new(struct vmproc *owner, ino_t ino, dev_t dev, int fd)
|
|||
if(!SLABALLOC(fdref)) return NULL;
|
||||
|
||||
fdref->fd = fd;
|
||||
fdref->owner = owner;
|
||||
fdref->refcount = 0;
|
||||
fdref->dev = dev;
|
||||
fdref->ino = ino;
|
||||
fdref->next = owner->fdrefs;
|
||||
owner->fdrefs = fdref;
|
||||
fdref->next = fdrefs;
|
||||
fdrefs = fdref;
|
||||
|
||||
return fdref;
|
||||
}
|
||||
|
|
@ -51,7 +109,6 @@ struct fdref *fdref_new(struct vmproc *owner, ino_t ino, dev_t dev, int fd)
|
|||
void fdref_ref(struct fdref *ref, struct vir_region *region)
|
||||
{
|
||||
assert(ref);
|
||||
assert(ref->owner == region->parent);
|
||||
region->param.file.fdref = ref;
|
||||
ref->refcount++;
|
||||
}
|
||||
|
|
@ -63,7 +120,6 @@ void fdref_deref(struct vir_region *region)
|
|||
|
||||
assert(ref);
|
||||
assert(ref->refcount > 0);
|
||||
assert(ref->owner == region->parent);
|
||||
|
||||
fd = ref->fd;
|
||||
region->param.file.fdref = NULL;
|
||||
|
|
@ -71,10 +127,10 @@ void fdref_deref(struct vir_region *region)
|
|||
assert(ref->refcount >= 0);
|
||||
if(ref->refcount > 0) return;
|
||||
|
||||
if(region->parent->fdrefs == ref) region->parent->fdrefs = ref->next;
|
||||
if(fdrefs == ref) fdrefs = ref->next;
|
||||
else {
|
||||
struct fdref *r;
|
||||
for(r = region->parent->fdrefs; r->next != ref; r = r->next)
|
||||
for(r = fdrefs; r->next != ref; r = r->next)
|
||||
;
|
||||
assert(r);
|
||||
assert(r->next == ref);
|
||||
|
|
@ -84,10 +140,6 @@ void fdref_deref(struct vir_region *region)
|
|||
SLABFREE(ref);
|
||||
ref = NULL;
|
||||
|
||||
if(region->parent->vm_flags & (VMF_EXITING|VMF_EXECING)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* If the last reference has disappeared, free the
|
||||
* ref object and asynchronously close the fd in VFS.
|
||||
*
|
||||
|
|
@ -95,34 +147,27 @@ void fdref_deref(struct vir_region *region)
|
|||
* unexpected, isn't a problem and can't be handled. VFS
|
||||
* will print a diagnostic.
|
||||
*/
|
||||
#if 1
|
||||
if(vfs_request(VMVFSREQ_FDCLOSE, fd, region->parent,
|
||||
0, 0, NULL, NULL, NULL, 0) != OK) {
|
||||
panic("fdref_deref: could not send close request");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
struct fdref *fdref_dedup_or_new(struct vmproc *owner,
|
||||
ino_t ino, dev_t dev, int fd)
|
||||
ino_t ino, dev_t dev, int fd, int mayclose)
|
||||
{
|
||||
struct fdref *fr;
|
||||
|
||||
for(fr = owner->fdrefs; fr; fr = fr->next) {
|
||||
assert(fr->owner == owner);
|
||||
if(fr->fd == fd) {
|
||||
assert(ino == fr->ino);
|
||||
assert(dev == fr->dev);
|
||||
return fr;
|
||||
}
|
||||
for(fr = fdrefs; fr; fr = fr->next) {
|
||||
if(ino == fr->ino && dev == fr->dev) {
|
||||
assert(fd != fr->fd);
|
||||
#if 1
|
||||
if(fd == fr->fd) {
|
||||
return fr;
|
||||
}
|
||||
if(!mayclose) continue;
|
||||
if(vfs_request(VMVFSREQ_FDCLOSE, fd, owner,
|
||||
0, 0, NULL, NULL, NULL, 0) != OK) {
|
||||
printf("fdref_dedup_or_new: could not close\n");
|
||||
}
|
||||
#endif
|
||||
return fr;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@ struct fdref {
|
|||
int refcount;
|
||||
dev_t dev;
|
||||
ino_t ino;
|
||||
struct vmproc *owner;
|
||||
struct fdref *next;
|
||||
int counting; /* sanity check */
|
||||
} *fdref;
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -60,7 +60,6 @@ int do_fork(message *msg)
|
|||
/* The child is basically a copy of the parent. */
|
||||
origpt = vmc->vm_pt;
|
||||
*vmc = *vmp;
|
||||
vmc->fdrefs = NULL;
|
||||
vmc->vm_slot = childproc;
|
||||
region_init(&vmc->vm_regions_avl);
|
||||
vmc->vm_endpoint = NONE; /* In case someone tries to use it. */
|
||||
|
|
|
|||
|
|
@ -153,7 +153,7 @@ int mappedfile_copy(struct vir_region *vr, struct vir_region *newvr)
|
|||
mappedfile_setfile(newvr->parent, newvr, vr->param.file.fdref->fd,
|
||||
vr->param.file.offset,
|
||||
vr->param.file.fdref->dev, vr->param.file.fdref->ino,
|
||||
vr->param.file.clearend, 0);
|
||||
vr->param.file.clearend, 0, 0);
|
||||
assert(newvr->param.file.inited);
|
||||
|
||||
return OK;
|
||||
|
|
@ -161,10 +161,12 @@ int mappedfile_copy(struct vir_region *vr, struct vir_region *newvr)
|
|||
|
||||
int mappedfile_setfile(struct vmproc *owner,
|
||||
struct vir_region *region, int fd, u64_t offset,
|
||||
dev_t dev, ino_t ino, u16_t clearend, int prefill)
|
||||
dev_t dev, ino_t ino, u16_t clearend, int prefill, int mayclosefd)
|
||||
{
|
||||
vir_bytes vaddr;
|
||||
struct fdref *newref = fdref_dedup_or_new(owner, ino, dev, fd);
|
||||
struct fdref *newref;
|
||||
|
||||
newref = fdref_dedup_or_new(owner, ino, dev, fd, mayclosefd);
|
||||
|
||||
assert(newref);
|
||||
assert(!region->param.file.inited);
|
||||
|
|
@ -245,4 +247,5 @@ static void mappedfile_delete(struct vir_region *region)
|
|||
assert(region->param.file.inited);
|
||||
assert(region->param.file.fdref);
|
||||
fdref_deref(region);
|
||||
region->param.file.inited = 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ static struct vir_region *mmap_region(struct vmproc *vmp, vir_bytes addr,
|
|||
static int mmap_file(struct vmproc *vmp,
|
||||
int vmfd, u32_t off_lo, u32_t off_hi, int flags,
|
||||
ino_t ino, dev_t dev, u64_t filesize, vir_bytes addr, vir_bytes len,
|
||||
vir_bytes *retaddr, u16_t clearend, int writable)
|
||||
vir_bytes *retaddr, u16_t clearend, int writable, int mayclosefd)
|
||||
{
|
||||
/* VFS has replied to a VMVFSREQ_FDLOOKUP request. */
|
||||
struct vir_region *vr;
|
||||
|
|
@ -136,7 +136,7 @@ static int mmap_file(struct vmproc *vmp,
|
|||
result = OK;
|
||||
|
||||
mappedfile_setfile(vmp, vr, vmfd,
|
||||
file_offset, dev, ino, clearend, 1);
|
||||
file_offset, dev, ino, clearend, 1, mayclosefd);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
|
@ -161,7 +161,7 @@ int do_vfs_mmap(message *m)
|
|||
m->m_u.m_vm_vfs.ino, m->m_u.m_vm_vfs.dev,
|
||||
(u64_t) LONG_MAX * VM_PAGE_SIZE,
|
||||
m->m_u.m_vm_vfs.vaddr, m->m_u.m_vm_vfs.len, &v,
|
||||
clearend, flags);
|
||||
clearend, flags, 0);
|
||||
}
|
||||
|
||||
static void mmap_file_cont(struct vmproc *vmp, message *replymsg, void *cbarg,
|
||||
|
|
@ -177,7 +177,7 @@ static void mmap_file_cont(struct vmproc *vmp, message *replymsg, void *cbarg,
|
|||
writable = 1;
|
||||
|
||||
if(replymsg->VMV_RESULT != OK) {
|
||||
printf("VM: VFS reply failed\n");
|
||||
printf("VM: VFS reply failed (%d)\n", replymsg->VMV_RESULT);
|
||||
sys_sysctl_stacktrace(vmp->vm_endpoint);
|
||||
result = origmsg->VMV_RESULT;
|
||||
} else {
|
||||
|
|
@ -187,7 +187,7 @@ static void mmap_file_cont(struct vmproc *vmp, message *replymsg, void *cbarg,
|
|||
replymsg->VMV_INO, replymsg->VMV_DEV,
|
||||
(u64_t) replymsg->VMV_SIZE_PAGES*PAGE_SIZE,
|
||||
origmsg->VMM_ADDR,
|
||||
origmsg->VMM_LEN, &v, 0, writable);
|
||||
origmsg->VMM_LEN, &v, 0, writable, 1);
|
||||
}
|
||||
|
||||
/* Unblock requesting process. */
|
||||
|
|
|
|||
|
|
@ -230,10 +230,12 @@ int do_vfs_reply(message *m);
|
|||
/* mem_file.c */
|
||||
int mappedfile_setfile(struct vmproc *owner, struct vir_region *region,
|
||||
int fd, u64_t offset,
|
||||
dev_t dev, ino_t ino, u16_t clearend, int prefill);
|
||||
dev_t dev, ino_t ino, u16_t clearend, int prefill, int mayclose);
|
||||
|
||||
/* fdref.c */
|
||||
struct fdref *fdref_new(struct vmproc *owner, ino_t ino, dev_t dev, int fd);
|
||||
struct fdref *fdref_dedup_or_new(struct vmproc *owner, ino_t ino, dev_t dev, int fd);
|
||||
struct fdref *fdref_dedup_or_new(struct vmproc *owner, ino_t ino, dev_t dev,
|
||||
int fd, int mayclose);
|
||||
void fdref_ref(struct fdref *ref, struct vir_region *region);
|
||||
void fdref_deref(struct vir_region *region);
|
||||
void fdref_sanitycheck(void);
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ struct vmproc {
|
|||
vir_bytes vm_region_top; /* highest vaddr last inserted */
|
||||
bitchunk_t vm_call_mask[VM_CALL_MASK_SIZE];
|
||||
int vm_slot; /* process table slot */
|
||||
struct fdref *fdrefs;
|
||||
#if VMSTATS
|
||||
int vm_bytecopies;
|
||||
#endif
|
||||
|
|
@ -32,6 +31,5 @@ struct vmproc {
|
|||
#define VMF_INUSE 0x001 /* slot contains a process */
|
||||
#define VMF_EXITING 0x002 /* PM is cleaning up this process */
|
||||
#define VMF_WATCHEXIT 0x008 /* Store in queryexit table */
|
||||
#define VMF_EXECING 0x010 /* exec() in progress */
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user