#include <minix/u64.h>
#include "file.h"
#include "fproc.h"
+#include "scratchpad.h"
#include "dmap.h"
#include <minix/vfsif.h>
#include "vnode.h"
}
/* 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);
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;
}
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");
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];
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 */
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 */
#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 */
#include <unistd.h>
#include "file.h"
#include "fproc.h"
+#include "scratchpad.h"
#include "lock.h"
#include "vnode.h"
#include "param.h"
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. */
/* 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);
}
#include "file.h"
#include "dmap.h"
#include "fproc.h"
+#include "scratchpad.h"
#include "vmnt.h"
#include "vnode.h"
#include "job.h"
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);
/* 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;
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;
#include <sys/svrctl.h>
#include "file.h"
#include "fproc.h"
+#include "scratchpad.h"
#include "dmap.h"
#include <minix/vfsif.h>
#include "vnode.h"
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:
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:
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;
#include <minix/u64.h>
#include "file.h"
#include "fproc.h"
+#include "scratchpad.h"
#include "dmap.h"
#include "lock.h"
#include "param.h"
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);
}
/* 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;
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;
/* 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);
#include <sys/time.h>
#include "file.h"
#include "fproc.h"
+#include "scratchpad.h"
#include "dmap.h"
#include "param.h"
#include "select.h"
*/
#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");
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;
- }
}
/*===========================================================================*
/*===========================================================================*
* 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);
}
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);
* 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);
}
} 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);
/* 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.
*/
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];
_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
#include <minix/u64.h>
#include "file.h"
#include "fproc.h"
+#include "scratchpad.h"
#include "param.h"
#include <dirent.h>
#include <assert.h>
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);
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);
}
* 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);
}
}
--- /dev/null
+#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
#include "file.h"
#include "fproc.h"
#include "lock.h"
+#include "scratchpad.h"
#include "vnode.h"
#include "vmnt.h"