diff --git a/servers/avfs/device.c b/servers/avfs/device.c index 21b42dddc..29130df29 100644 --- a/servers/avfs/device.c +++ b/servers/avfs/device.c @@ -32,6 +32,7 @@ #include #include "file.h" #include "fproc.h" +#include "scratchpad.h" #include "dmap.h" #include #include "vnode.h" @@ -878,7 +879,8 @@ PUBLIC int clone_opcl( } /* Drop old node and use the new values */ - vp = fp->fp_filp[m_in.fd]->filp_vno; + assert(FD_ISSET(scratch(fp).file.fd_nr, &fp->fp_filp_inuse)); + vp = fp->fp_filp[scratch(fp).file.fd_nr]->filp_vno; unlock_vnode(vp); put_vnode(vp); @@ -896,7 +898,7 @@ PUBLIC int clone_opcl( vp->v_sdev = dev; vp->v_fs_count = 1; vp->v_ref_count = 1; - fp->fp_filp[m_in.fd]->filp_vno = vp; + fp->fp_filp[scratch(fp).file.fd_nr]->filp_vno = vp; } dev_mess.REP_STATUS = OK; } @@ -983,9 +985,9 @@ PUBLIC void cdev_up(int maj) if(rfp->fp_pid == PID_FREE) continue; if(rfp->fp_blocked_on != FP_BLOCKED_ON_DOPEN) continue; + fd_nr = scratch(rfp).file.fd_nr; printf("VFS: dev_up: found process in FP_BLOCKED_ON_DOPEN, fd %d\n", - rfp->fp_blocked.fd_nr); - fd_nr = rfp->fp_blocked.fd_nr; + fd_nr); rfilp = rfp->fp_filp[fd_nr]; vp = rfilp->filp_vno; if (!vp) panic("VFS: restart_reopen: no vp"); @@ -1091,7 +1093,7 @@ int maj; if (rfp->fp_blocked_on == FP_BLOCKED_ON_DOPEN || !(rfp->fp_flags & FP_SUSP_REOPEN)) continue; - fd_nr = rfp->fp_blocked.fd_nr; + fd_nr = scratch(rfp).file.fd_nr; printf("VFS: restart_reopen: process in FP_BLOCKED_ON_DOPEN fd=%d\n", fd_nr); rfilp = rfp->fp_filp[fd_nr]; diff --git a/servers/avfs/fproc.h b/servers/avfs/fproc.h index ce33ecd52..f0ae8419d 100644 --- a/servers/avfs/fproc.h +++ b/servers/avfs/fproc.h @@ -25,14 +25,9 @@ EXTERN struct fproc { fd_set fp_cloexec_set; /* bit map for POSIX Table 6-2 FD_CLOEXEC */ dev_t fp_tty; /* major/minor of controlling tty */ + int fp_blocked_on; /* what is it blocked on */ int fp_block_callnr; /* blocked call if rd/wr can't finish */ - union blocked { - int fd_nr; /* place to save fd if rd/wr can't finish */ - struct filp *bfilp; /* place to save filp if rd/wr can't finish */ - } fp_blocked; - char *fp_buffer; /* place to save buffer if rd/wr can't finish*/ - int fp_nbytes; /* place to save bytes if rd/wr can't finish */ int fp_cum_io_partial; /* partial byte count if rd/wr can't finish */ endpoint_t fp_task; /* which task is proc suspended on */ endpoint_t fp_ioproc; /* proc no. in suspended-on i/o message */ @@ -46,6 +41,7 @@ EXTERN struct fproc { int fp_ngroups; /* number of supplemental groups */ gid_t fp_sgroups[NGROUPS_MAX];/* supplemental groups */ mode_t fp_umask; /* mask set by umask system call */ + message *fp_sendrec; /* request/reply to/from FS/driver */ mutex_t fp_lock; /* mutex to lock fproc object */ struct job fp_job; /* pending job */ diff --git a/servers/avfs/glo.h b/servers/avfs/glo.h index 95a38f02b..0995c144b 100644 --- a/servers/avfs/glo.h +++ b/servers/avfs/glo.h @@ -33,6 +33,7 @@ EXTERN message m_out; /* the output message used for reply */ #endif # define call_nr (m_in.m_type) # define super_user (fp->fp_effuid == SU_UID ? 1 : 0) +# define scratch(p) (scratchpad[((int) ((p) - fproc))]) EXTERN struct worker_thread *self; EXTERN endpoint_t receive_from;/* endpoint with pending reply */ EXTERN int force_sync; /* toggle forced synchronous communication */ diff --git a/servers/avfs/lock.c b/servers/avfs/lock.c index 58eddb077..36ab59351 100644 --- a/servers/avfs/lock.c +++ b/servers/avfs/lock.c @@ -12,6 +12,7 @@ #include #include "file.h" #include "fproc.h" +#include "scratchpad.h" #include "lock.h" #include "vnode.h" #include "param.h" @@ -29,13 +30,11 @@ int req; /* either F_SETLK or F_SETLKW */ mode_t mo; off_t first, last; struct flock flock; - vir_bytes user_flock; struct file_lock *flp, *flp2, *empty; /* Fetch the flock structure from user space. */ - user_flock = (vir_bytes) m_in.name1; - r = sys_datacopy(who_e, (vir_bytes) user_flock, VFS_PROC_NR, - (vir_bytes) &flock, (phys_bytes) sizeof(flock)); + r = sys_datacopy(who_e, (vir_bytes) scratch(fp).io.io_buffer, VFS_PROC_NR, + (vir_bytes) &flock, sizeof(flock)); if (r != OK) return(EINVAL); /* Make some error checks. */ @@ -149,7 +148,7 @@ int req; /* either F_SETLK or F_SETLKW */ /* Copy the flock structure back to the caller. */ r = sys_datacopy(VFS_PROC_NR, (vir_bytes) &flock, - who_e, (vir_bytes) user_flock, (phys_bytes) sizeof(flock)); + who_e, (vir_bytes) scratch(fp).io.io_buffer, sizeof(flock)); return(r); } diff --git a/servers/avfs/main.c b/servers/avfs/main.c index 02deb4ce9..85ac294b8 100644 --- a/servers/avfs/main.c +++ b/servers/avfs/main.c @@ -29,6 +29,7 @@ #include "file.h" #include "dmap.h" #include "fproc.h" +#include "scratchpad.h" #include "vmnt.h" #include "vnode.h" #include "job.h" @@ -348,15 +349,15 @@ PRIVATE void *do_pending_pipe(void *arg) lock_proc(fp, 1 /* force lock */); - f = fp->fp_blocked.bfilp; + f = scratch(fp).file.filp; assert(f != NULL); - fp->fp_blocked.bfilp = NULL; + scratch(fp).file.filp = NULL; locktype = (call_nr == READ) ? VNODE_READ : VNODE_WRITE; op = (call_nr == READ) ? READING : WRITING; lock_filp(f, locktype); - r = rw_pipe(op, who_e, f, fp->fp_buffer, fp->fp_nbytes); + r = rw_pipe(op, who_e, f, scratch(fp).io.io_buffer, scratch(fp).io.io_nbytes); if (r != SUSPEND) /* Do we have results to report? */ reply(who_e, r); @@ -821,14 +822,14 @@ PRIVATE void service_pm_postponed(void) /* Copy parameters first. m_in gets overwritten when creating core * file. */ - m_out.m_type = PM_CORE_REPLY; - m_out.PM_PROC = m_in.PM_PROC; - m_out.PM_TRACED_PROC = m_in.PM_TRACED_PROC; r = pm_dumpcore(m_in.PM_PROC, m_in.PM_TERM_SIG, (vir_bytes) m_in.PM_PATH); /* Reply status to PM */ + m_out.m_type = PM_CORE_REPLY; + m_out.PM_PROC = m_in.PM_PROC; + m_out.PM_TRACED_PROC = m_in.PM_TRACED_PROC; m_out.PM_STATUS = r; break; @@ -961,9 +962,9 @@ struct fproc *rfp; fp = rfp; blocked_on = rfp->fp_blocked_on; m_in.m_type = rfp->fp_block_callnr; - m_in.fd = rfp->fp_blocked.fd_nr; - m_in.buffer = rfp->fp_buffer; - m_in.nbytes = rfp->fp_nbytes; + m_in.fd = scratch(fp).file.fd_nr; + m_in.buffer = scratch(fp).io.io_buffer; + m_in.nbytes = scratch(fp).io.io_nbytes; rfp->fp_blocked_on = FP_BLOCKED_ON_NONE; /* no longer blocked */ rfp->fp_flags &= ~FP_REVIVED; diff --git a/servers/avfs/misc.c b/servers/avfs/misc.c index 2cb7f3b8b..08a1afa48 100644 --- a/servers/avfs/misc.c +++ b/servers/avfs/misc.c @@ -33,6 +33,7 @@ #include #include "file.h" #include "fproc.h" +#include "scratchpad.h" #include "dmap.h" #include #include "vnode.h" @@ -157,9 +158,14 @@ PUBLIC int do_fcntl() int new_fd, fl, r = OK; tll_access_t locktype; + scratch(fp).file.fd_nr = m_in.fd; + scratch(fp).io.io_buffer = m_in.buffer; + scratch(fp).io.io_nbytes = m_in.nbytes; /* a.k.a. m_in.request */ + /* Is the file descriptor valid? */ locktype = (m_in.request == F_FREESP) ? VNODE_WRITE : VNODE_READ; - if ((f = get_filp(m_in.fd, locktype)) == NULL) return(err_code); + if ((f = get_filp(scratch(fp).file.fd_nr, locktype)) == NULL) + return(err_code); switch (m_in.request) { case F_DUPFD: @@ -175,15 +181,17 @@ PUBLIC int do_fcntl() case F_GETFD: /* Get close-on-exec flag (FD_CLOEXEC in POSIX Table 6-2). */ - r = FD_ISSET(m_in.fd, &fp->fp_cloexec_set) ? FD_CLOEXEC : 0; + r = 0; + if (FD_ISSET(scratch(fp).file.fd_nr, &fp->fp_cloexec_set)) + r = FD_CLOEXEC; break; case F_SETFD: /* Set close-on-exec flag (FD_CLOEXEC in POSIX Table 6-2). */ if(m_in.addr & FD_CLOEXEC) - FD_SET(m_in.fd, &fp->fp_cloexec_set); + FD_SET(scratch(fp).file.fd_nr, &fp->fp_cloexec_set); else - FD_CLR(m_in.fd, &fp->fp_cloexec_set); + FD_CLR(scratch(fp).file.fd_nr, &fp->fp_cloexec_set); break; case F_GETFL: @@ -207,9 +215,7 @@ PUBLIC int do_fcntl() case F_FREESP: { - /* Free a section of a file. Preparation is done here, actual freeing - * in freesp_inode(). - */ + /* Free a section of a file */ off_t start, end; struct flock flock_arg; signed long offset; diff --git a/servers/avfs/open.c b/servers/avfs/open.c index 5358c3171..dc8948ca6 100644 --- a/servers/avfs/open.c +++ b/servers/avfs/open.c @@ -21,6 +21,7 @@ #include #include "file.h" #include "fproc.h" +#include "scratchpad.h" #include "dmap.h" #include "lock.h" #include "param.h" @@ -99,7 +100,7 @@ PUBLIC int common_open(char path[PATH_MAX], int oflags, mode_t omode) if (!bits) return(EINVAL); /* See if file descriptor and filp slots are available. */ - if ((r = get_fd(0, bits, &m_in.fd, &filp)) != OK) return(r); + if ((r = get_fd(0, bits, &(scratch(fp).file.fd_nr), &filp)) != OK) return(r); lookup_init(&resolve, path, PATH_NOFLAGS, &vmp, &vp); @@ -129,8 +130,8 @@ PUBLIC int common_open(char path[PATH_MAX], int oflags, mode_t omode) } /* Claim the file descriptor and filp slot and fill them in. */ - fp->fp_filp[m_in.fd] = filp; - FD_SET(m_in.fd, &fp->fp_filp_inuse); + fp->fp_filp[scratch(fp).file.fd_nr] = filp; + FD_SET(scratch(fp).file.fd_nr, &fp->fp_filp_inuse); filp->filp_count = 1; filp->filp_vno = vp; filp->filp_flags = oflags; @@ -242,7 +243,7 @@ PUBLIC int common_open(char path[PATH_MAX], int oflags, mode_t omode) filp->filp_count = 0; /* don't find self */ if ((filp2 = find_filp(vp, b)) != NULL) { /* Co-reader or writer found. Use it.*/ - fp->fp_filp[m_in.fd] = filp2; + fp->fp_filp[scratch(fp).file.fd_nr] = filp2; filp2->filp_count++; filp2->filp_vno = vp; filp2->filp_flags = oflags; @@ -271,14 +272,14 @@ PUBLIC int common_open(char path[PATH_MAX], int oflags, mode_t omode) /* If error, release inode. */ if (r != OK) { if (r != SUSPEND) { - fp->fp_filp[m_in.fd] = NULL; - FD_CLR(m_in.fd, &fp->fp_filp_inuse); + fp->fp_filp[scratch(fp).file.fd_nr] = NULL; + FD_CLR(scratch(fp).file.fd_nr, &fp->fp_filp_inuse); filp->filp_count = 0; filp->filp_vno = NULL; put_vnode(vp); } } else { - r = m_in.fd; + r = scratch(fp).file.fd_nr; } return(r); diff --git a/servers/avfs/pipe.c b/servers/avfs/pipe.c index 2a841ba19..b339f6baf 100644 --- a/servers/avfs/pipe.c +++ b/servers/avfs/pipe.c @@ -27,6 +27,7 @@ #include #include "file.h" #include "fproc.h" +#include "scratchpad.h" #include "dmap.h" #include "param.h" #include "select.h" @@ -284,9 +285,6 @@ PUBLIC void suspend(int why) */ #if DO_SANITYCHECKS - if (why == FP_BLOCKED_ON_PIPE) - panic("suspend: called for FP_BLOCKED_ON_PIPE"); - if(fp_is_blocked(fp)) panic("suspend: called for suspended process"); @@ -294,29 +292,16 @@ PUBLIC void suspend(int why) panic("suspend: called for FP_BLOCKED_ON_NONE"); #endif - if (why == FP_BLOCKED_ON_POPEN) + if (why == FP_BLOCKED_ON_POPEN || why == FP_BLOCKED_ON_PIPE) /* #procs susp'ed on pipe*/ susp_count++; - if (why == FP_BLOCKED_ON_POPEN || why == FP_BLOCKED_ON_DOPEN || - why == FP_BLOCKED_ON_LOCK || why == FP_BLOCKED_ON_OTHER) - fp->fp_blocked.fd_nr = m_in.fd; - else - fp->fp_blocked.fd_nr = 0; - fp->fp_blocked_on = why; assert(fp->fp_grant == GRANT_INVALID || !GRANT_VALID(fp->fp_grant)); fp->fp_block_callnr = call_nr; fp->fp_flags &= ~FP_SUSP_REOPEN; /* Clear this flag. The caller * can set it when needed. */ - if (why == FP_BLOCKED_ON_LOCK) { - fp->fp_buffer = (char *) m_in.name1; /* third arg to fcntl() */ - fp->fp_nbytes = m_in.request; /* second arg to fcntl() */ - } else { - fp->fp_buffer = m_in.buffer; /* for reads and writes */ - fp->fp_nbytes = m_in.nbytes; - } } /*===========================================================================* @@ -334,30 +319,23 @@ PUBLIC void wait_for(endpoint_t who) /*===========================================================================* * pipe_suspend * *===========================================================================*/ -PUBLIC void pipe_suspend(rw_flag, filp, buf, size) -int rw_flag; +PUBLIC void pipe_suspend(filp, buf, size) struct filp *filp; char *buf; size_t size; { /* Take measures to suspend the processing of the present system call. * Store the parameters to be used upon resuming in the process table. - * (Actually they are not used when a process is waiting for an I/O device, - * but they are needed for pipes, and it is not worth making the distinction.) - * The SUSPEND pseudo error should be returned after calling suspend(). */ #if DO_SANITYCHECKS if(fp_is_blocked(fp)) panic("pipe_suspend: called for suspended process"); #endif - susp_count++; /* #procs susp'ed on pipe*/ - fp->fp_blocked_on = FP_BLOCKED_ON_PIPE; - assert(!GRANT_VALID(fp->fp_grant)); - fp->fp_blocked.bfilp = filp; - fp->fp_block_callnr = (rw_flag == READING) ? READ : WRITE; - fp->fp_buffer = buf; - fp->fp_nbytes = size; + scratch(fp).file.filp = filp; + scratch(fp).io.io_buffer = buf; + scratch(fp).io.io_nbytes = size; + suspend(FP_BLOCKED_ON_PIPE); } @@ -430,16 +408,18 @@ int count; /* max number of processes to release */ rp->fp_blocked_on == FP_BLOCKED_ON_DOPEN || rp->fp_blocked_on == FP_BLOCKED_ON_LOCK || rp->fp_blocked_on == FP_BLOCKED_ON_OTHER) { - if (rp->fp_filp[rp->fp_blocked.fd_nr] == NULL) + if (!FD_ISSET(scratch(rp).file.fd_nr, + &rp->fp_filp_inuse)) continue; - if (rp->fp_filp[rp->fp_blocked.fd_nr]->filp_vno != vp) + if (rp->fp_filp[scratch(rp).file.fd_nr]->filp_vno != vp) continue; - } else { - if (rp->fp_blocked.bfilp == NULL) + } else if (rp->fp_blocked_on == FP_BLOCKED_ON_PIPE) { + if (scratch(rp).file.filp == NULL) continue; - if (rp->fp_blocked.bfilp->filp_vno != vp) + if (scratch(rp).file.filp->filp_vno != vp) continue; - } + } else + continue; /* We found the vnode. Revive process. */ revive(rp->fp_endpoint, 0); @@ -478,14 +458,14 @@ int returned; /* if hanging on task, how many bytes read */ * the proc must be restarted so it can try again. */ blocked_on = rfp->fp_blocked_on; - fd_nr = rfp->fp_blocked.fd_nr; + fd_nr = scratch(rfp).file.fd_nr; if (blocked_on == FP_BLOCKED_ON_PIPE || blocked_on == FP_BLOCKED_ON_LOCK) { /* Revive a process suspended on a pipe or lock. */ rfp->fp_flags |= FP_REVIVED; reviving++; /* process was waiting on pipe or lock */ } else if (blocked_on == FP_BLOCKED_ON_DOPEN) { rfp->fp_blocked_on = FP_BLOCKED_ON_NONE; - rfp->fp_blocked.fd_nr = 0; + scratch(rfp).file.fd_nr = 0; if (returned < 0) { fil_ptr = rfp->fp_filp[fd_nr]; lock_filp(fil_ptr, VNODE_OPCL); @@ -505,7 +485,7 @@ int returned; /* if hanging on task, how many bytes read */ } } else { rfp->fp_blocked_on = FP_BLOCKED_ON_NONE; - rfp->fp_blocked.fd_nr = 0; + scratch(rfp).file.fd_nr = 0; if (blocked_on == FP_BLOCKED_ON_POPEN) { /* process blocked in open or create */ reply(proc_nr_e, fd_nr); @@ -515,7 +495,7 @@ int returned; /* if hanging on task, how many bytes read */ /* Revive a process suspended on TTY or other device. * Pretend it wants only what there is. */ - rfp->fp_nbytes = returned; + scratch(rfp).io.io_nbytes = returned; /* If a grant has been issued by FS for this I/O, revoke * it again now that I/O is done. */ @@ -592,7 +572,7 @@ int proc_nr_e; break; } - fild = rfp->fp_blocked.fd_nr; + fild = scratch(rfp).file.fd_nr; if (fild < 0 || fild >= OPEN_MAX) panic("file descriptor out-of-range"); f = rfp->fp_filp[fild]; diff --git a/servers/avfs/proto.h b/servers/avfs/proto.h index 12db0386e..327935bd8 100644 --- a/servers/avfs/proto.h +++ b/servers/avfs/proto.h @@ -196,8 +196,7 @@ _PROTOTYPE( int pipe_check, (struct vnode *vp, int rw_flag, _PROTOTYPE( void release, (struct vnode *vp, int call_nr, int count) ); _PROTOTYPE( void revive, (int proc_nr, int bytes) ); _PROTOTYPE( void suspend, (int task) ); -_PROTOTYPE( void pipe_suspend, (int rw_flag, struct filp *rfilp, - char *buf, size_t size) ); +_PROTOTYPE( void pipe_suspend, (struct filp *rfilp, char *buf, size_t size)); _PROTOTYPE( void unsuspend_by_endpt, (endpoint_t) ); _PROTOTYPE( void wait_for, (endpoint_t) ); #if DO_SANITYCHECKS diff --git a/servers/avfs/read.c b/servers/avfs/read.c index 24f3eb677..13df38ae0 100644 --- a/servers/avfs/read.c +++ b/servers/avfs/read.c @@ -17,6 +17,7 @@ #include #include "file.h" #include "fproc.h" +#include "scratchpad.h" #include "param.h" #include #include @@ -78,18 +79,24 @@ int rw_flag; /* READING or WRITING */ tll_access_t locktype; int r; + scratch(fp).file.fd_nr = m_in.fd; + scratch(fp).io.io_buffer = m_in.buffer; + scratch(fp).io.io_nbytes = (size_t) m_in.nbytes; + locktype = (rw_flag == READING) ? VNODE_READ : VNODE_WRITE; - if ((f = get_filp(m_in.fd, locktype)) == NULL) return(err_code); + if ((f = get_filp(scratch(fp).file.fd_nr, locktype)) == NULL) + return(err_code); if (((f->filp_mode) & (rw_flag == READING ? R_BIT : W_BIT)) == 0) { unlock_filp(f); return(f->filp_mode == FILP_CLOSED ? EIO : EBADF); } - if (m_in.nbytes == 0) { + if (scratch(fp).io.io_nbytes == 0) { unlock_filp(f); return(0); /* so char special files need not check for 0*/ } - r = read_write(rw_flag, f, m_in.buffer, m_in.nbytes, who_e); + r = read_write(rw_flag, f, scratch(fp).io.io_buffer, scratch(fp).io.io_nbytes, + who_e); unlock_filp(f); return(r); @@ -260,7 +267,7 @@ size_t req_size; r = pipe_check(vp, rw_flag, oflags, req_size, position, 0); if (r <= 0) { - if (r == SUSPEND) pipe_suspend(rw_flag, f, buf, req_size); + if (r == SUSPEND) pipe_suspend(f, buf, req_size); return(r); } @@ -328,7 +335,7 @@ size_t req_size; * non-atomic */ fp->fp_cum_io_partial = cum_io; - pipe_suspend(rw_flag, f, buf, req_size); + pipe_suspend(f, buf, req_size); return(SUSPEND); } } diff --git a/servers/avfs/scratchpad.h b/servers/avfs/scratchpad.h new file mode 100644 index 000000000..f33a01c3a --- /dev/null +++ b/servers/avfs/scratchpad.h @@ -0,0 +1,18 @@ +#ifndef __VFS_SCRATCHPAD_H__ +#define __VFS_SCRATCHPAD_H__ + +/* This is the per-process information. A slot is reserved for each potential + * process. Thus NR_PROCS must be the same as in the kernel. + */ +EXTERN struct scratchpad { + union sp_data { + int fd_nr; + struct filp *filp; + } file; + struct io_cmd { + char *io_buffer; + size_t io_nbytes; + } io; +} scratchpad[NR_PROCS]; + +#endif diff --git a/servers/avfs/table.c b/servers/avfs/table.c index 792e3ac74..c4a4173bc 100644 --- a/servers/avfs/table.c +++ b/servers/avfs/table.c @@ -10,6 +10,7 @@ #include "file.h" #include "fproc.h" #include "lock.h" +#include "scratchpad.h" #include "vnode.h" #include "vmnt.h"