#include <minix/ioctl.h>
#include <minix/u64.h>
#include "file.h"
-#include "scratchpad.h"
#include "dmap.h"
#include <minix/vfsif.h>
#include "vnode.h"
}
lock_vnode(vp, VNODE_OPCL);
- assert(fp->fp_filp[scratch(fp).file.fd_nr] != NULL);
- unlock_vnode(fp->fp_filp[scratch(fp).file.fd_nr]->filp_vno);
- put_vnode(fp->fp_filp[scratch(fp).file.fd_nr]->filp_vno);
+ assert(fp->fp_filp[fp->fp_fd] != NULL);
+ unlock_vnode(fp->fp_filp[fp->fp_fd]->filp_vno);
+ put_vnode(fp->fp_filp[fp->fp_fd]->filp_vno);
vp->v_fs_e = res.fs_e;
vp->v_vmnt = NULL;
vp->v_sdev = dev;
vp->v_fs_count = 1;
vp->v_ref_count = 1;
- fp->fp_filp[scratch(fp).file.fd_nr]->filp_vno = vp;
+ fp->fp_filp[fp->fp_fd]->filp_vno = vp;
return OK;
}
dev_t dev;
vir_bytes argx;
- scratch(fp).file.fd_nr = job_m_in.m_lc_vfs_ioctl.fd;
+ fp->fp_fd = job_m_in.m_lc_vfs_ioctl.fd;
ioctlrequest = job_m_in.m_lc_vfs_ioctl.req;
argx = (vir_bytes)job_m_in.m_lc_vfs_ioctl.arg;
- if ((f = get_filp(scratch(fp).file.fd_nr, VNODE_READ)) == NULL)
+ if ((f = get_filp(fp->fp_fd, VNODE_READ)) == NULL)
return(err_code);
vp = f->filp_vno; /* get vnode pointer */
if (!S_ISCHR(vp->v_mode) && !S_ISBLK(vp->v_mode)) {
endpoint_t fp_task; /* which task is proc suspended on */
cp_grant_id_t fp_grant; /* revoke this grant on unsuspend if > -1 */
+ int fp_fd; /* file descriptor for blocking call */
+ vir_bytes fp_io_buffer; /* user buffer address for ongoing I/O */
+ size_t fp_io_nbytes; /* number of bytes left for ongoing I/O */
+
uid_t fp_realuid; /* real user id */
uid_t fp_effuid; /* effective user id */
gid_t fp_realgid; /* real group id */
# define job_m_out (self->w_m_out)
# define job_call_nr (job_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 int deadlock_resolving;
EXTERN mutex_t bsf_lock;/* Global lock for access to block special files */
#include "file.h"
#include "path.h"
#include "vnode.h"
-#include "scratchpad.h"
/*===========================================================================*
* do_link *
int r;
off_t length;
- scratch(fp).file.fd_nr = job_m_in.m_lc_vfs_truncate.fd;
+ fp->fp_fd = job_m_in.m_lc_vfs_truncate.fd;
length = job_m_in.m_lc_vfs_truncate.offset;
if (length < 0) return(EINVAL);
/* File is already opened; get a vnode pointer from filp */
- if ((rfilp = get_filp(scratch(fp).file.fd_nr, VNODE_WRITE)) == NULL)
+ if ((rfilp = get_filp(fp->fp_fd, VNODE_WRITE)) == NULL)
return(err_code);
vp = rfilp->filp_vno;
#include <fcntl.h>
#include <unistd.h>
#include "file.h"
-#include "scratchpad.h"
#include "lock.h"
#include "vnode.h"
struct file_lock *flp, *flp2, *empty;
/* Fetch the flock structure from user space. */
- r = sys_datacopy_wrapper(who_e, scratch(fp).io.io_buffer, VFS_PROC_NR,
+ r = sys_datacopy_wrapper(who_e, fp->fp_io_buffer, VFS_PROC_NR,
(vir_bytes) &flock, sizeof(flock));
if (r != OK) return(EINVAL);
/* Copy the flock structure back to the caller. */
r = sys_datacopy_wrapper(VFS_PROC_NR, (vir_bytes) &flock, who_e,
- scratch(fp).io.io_buffer, sizeof(flock));
+ fp->fp_io_buffer, sizeof(flock));
return(r);
}
#include <minix/debug.h>
#include <minix/vfsif.h>
#include "file.h"
-#include "scratchpad.h"
#include "vmnt.h"
#include "vnode.h"
struct filp *f;
tll_access_t locktype;
- f = scratch(fp).file.filp;
+ f = fp->fp_filp[fp->fp_fd];
assert(f != NULL);
- scratch(fp).file.filp = NULL;
locktype = (job_call_nr == VFS_READ) ? VNODE_READ : VNODE_WRITE;
op = (job_call_nr == VFS_READ) ? READING : WRITING;
lock_filp(f, locktype);
- r = rw_pipe(op, who_e, f, scratch(fp).io.io_buffer, scratch(fp).io.io_nbytes);
+ r = rw_pipe(op, who_e, f, fp->fp_io_buffer, fp->fp_io_nbytes);
if (r != SUSPEND) { /* Do we have results to report? */
/* Process is writing, but there is no reader. Send a SIGPIPE signal.
case VFS_READ:
case VFS_WRITE:
assert(blocked_on == FP_BLOCKED_ON_PIPE);
- m_in.m_lc_vfs_readwrite.fd = scratch(rfp).file.fd_nr;
- m_in.m_lc_vfs_readwrite.buf = scratch(rfp).io.io_buffer;
- m_in.m_lc_vfs_readwrite.len = scratch(rfp).io.io_nbytes;
+ m_in.m_lc_vfs_readwrite.fd = rfp->fp_fd;
+ m_in.m_lc_vfs_readwrite.buf = rfp->fp_io_buffer;
+ m_in.m_lc_vfs_readwrite.len = rfp->fp_io_nbytes;
break;
case VFS_FCNTL:
assert(blocked_on == FP_BLOCKED_ON_LOCK);
- m_in.m_lc_vfs_fcntl.fd = scratch(rfp).file.fd_nr;
- m_in.m_lc_vfs_fcntl.cmd = scratch(rfp).io.io_nbytes;
- m_in.m_lc_vfs_fcntl.arg_ptr = scratch(rfp).io.io_buffer;
+ m_in.m_lc_vfs_fcntl.fd = rfp->fp_fd;
+ m_in.m_lc_vfs_fcntl.cmd = rfp->fp_io_nbytes;
+ m_in.m_lc_vfs_fcntl.arg_ptr = rfp->fp_io_buffer;
assert(m_in.m_lc_vfs_fcntl.cmd == F_SETLKW);
break;
default:
#include <sys/svrctl.h>
#include <sys/resource.h>
#include "file.h"
-#include "scratchpad.h"
#include <minix/vfsif.h>
#include "vnode.h"
#include "vmnt.h"
int new_fd, fl, r = OK, fcntl_req, fcntl_argx;
tll_access_t locktype;
- scratch(fp).file.fd_nr = job_m_in.m_lc_vfs_fcntl.fd;
- scratch(fp).io.io_buffer = job_m_in.m_lc_vfs_fcntl.arg_ptr;
- scratch(fp).io.io_nbytes = job_m_in.m_lc_vfs_fcntl.cmd;
+ fp->fp_fd = job_m_in.m_lc_vfs_fcntl.fd;
+ fp->fp_io_buffer = job_m_in.m_lc_vfs_fcntl.arg_ptr;
+ fp->fp_io_nbytes = job_m_in.m_lc_vfs_fcntl.cmd;
fcntl_req = job_m_in.m_lc_vfs_fcntl.cmd;
fcntl_argx = job_m_in.m_lc_vfs_fcntl.arg_int;
/* Is the file descriptor valid? */
locktype = (fcntl_req == F_FREESP) ? VNODE_WRITE : VNODE_READ;
- if ((f = get_filp(scratch(fp).file.fd_nr, locktype)) == NULL)
+ if ((f = get_filp(fp->fp_fd, locktype)) == NULL)
return(err_code);
switch (fcntl_req) {
case F_GETFD:
/* Get close-on-exec flag (FD_CLOEXEC in POSIX Table 6-2). */
r = 0;
- if (FD_ISSET(scratch(fp).file.fd_nr, &fp->fp_cloexec_set))
+ if (FD_ISSET(fp->fp_fd, &fp->fp_cloexec_set))
r = FD_CLOEXEC;
break;
case F_SETFD:
/* Set close-on-exec flag (FD_CLOEXEC in POSIX Table 6-2). */
if (fcntl_argx & FD_CLOEXEC)
- FD_SET(scratch(fp).file.fd_nr, &fp->fp_cloexec_set);
+ FD_SET(fp->fp_fd, &fp->fp_cloexec_set);
else
- FD_CLR(scratch(fp).file.fd_nr, &fp->fp_cloexec_set);
+ FD_CLR(fp->fp_fd, &fp->fp_cloexec_set);
break;
case F_GETFL:
else if (!(f->filp_mode & W_BIT)) r = EBADF;
else {
/* Copy flock data from userspace. */
- r = sys_datacopy_wrapper(who_e, scratch(fp).io.io_buffer,
+ r = sys_datacopy_wrapper(who_e, fp->fp_io_buffer,
SELF, (vir_bytes) &flock_arg, sizeof(flock_arg));
}
dev_t dev;
int r = OK;
- scratch(fp).file.fd_nr = job_m_in.m_lc_vfs_fsync.fd;
+ fp->fp_fd = job_m_in.m_lc_vfs_fsync.fd;
- if ((rfilp = get_filp(scratch(fp).file.fd_nr, VNODE_READ)) == NULL)
+ if ((rfilp = get_filp(fp->fp_fd, VNODE_READ)) == NULL)
return(err_code);
dev = rfilp->filp_vno->v_dev;
char core_path[PATH_MAX];
char proc_name[PROC_NAME_LEN];
- /* if a process is blocked, scratch(fp).file.fd_nr holds the fd it's blocked
- * on. free it up for use by common_open().
+ /* if a process is blocked, fp->fp_fd holds the fd it's blocked on.
+ * free it up for use by common_open().
*/
if (fp_is_blocked(fp))
unpause();
#include <minix/com.h>
#include <minix/u64.h>
#include "file.h"
-#include "scratchpad.h"
#include "lock.h"
#include <sys/dirent.h>
#include <assert.h>
if (!bits) return(EINVAL);
/* See if file descriptor and filp slots are available. */
- if ((r = get_fd(fp, start, bits, &(scratch(fp).file.fd_nr),
- &filp)) != OK)
+ if ((r = get_fd(fp, start, bits, &fp->fp_fd, &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[scratch(fp).file.fd_nr] = filp;
+ fp->fp_filp[fp->fp_fd] = filp;
filp->filp_count = 1;
filp->filp_vno = vp;
filp->filp_flags = oflags;
if (oflags & O_CLOEXEC)
- FD_SET(scratch(fp).file.fd_nr, &fp->fp_cloexec_set);
+ FD_SET(fp->fp_fd, &fp->fp_cloexec_set);
/* Only do the normal open code if we didn't just create the file. */
if (exist) {
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[scratch(fp).file.fd_nr] = filp2;
+ fp->fp_filp[fp->fp_fd] = 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[scratch(fp).file.fd_nr] = NULL;
+ fp->fp_filp[fp->fp_fd] = NULL;
filp->filp_count = 0;
filp->filp_vno = NULL;
put_vnode(vp);
}
} else {
- r = scratch(fp).file.fd_nr;
+ r = fp->fp_fd;
}
return(r);
#include <sys/select.h>
#include <sys/time.h>
#include "file.h"
-#include "scratchpad.h"
#include <minix/vfsif.h>
#include "vnode.h"
#include "vmnt.h"
* Store the parameters to be used upon resuming in the process table.
*/
- scratch(fp).file.filp = filp;
- scratch(fp).io.io_buffer = buf;
- scratch(fp).io.io_nbytes = size;
+ /* We can only get here through an I/O call, which comes with a file
+ * descriptor, and that file descriptor must therefore correspond to the
+ * target file pointer of the I/O request. The process is blocked on the I/O
+ * call, and thus, the file descriptor will remain valid. Therefore, we can,
+ * and will, use the file descriptor to get the file pointer again later.
+ */
+ assert(fp->fp_filp[fp->fp_fd] == filp);
+
+ fp->fp_io_buffer = buf;
+ fp->fp_io_nbytes = size;
suspend(FP_BLOCKED_ON_PIPE);
}
*/
if (rp->fp_blocked_on == FP_BLOCKED_ON_POPEN ||
+ rp->fp_blocked_on == FP_BLOCKED_ON_PIPE ||
rp->fp_blocked_on == FP_BLOCKED_ON_LOCK ||
rp->fp_blocked_on == FP_BLOCKED_ON_OTHER) {
- f = rp->fp_filp[scratch(rp).file.fd_nr];
+ f = rp->fp_filp[rp->fp_fd];
if (f == NULL || f->filp_mode == FILP_CLOSED)
continue;
- if (rp->fp_filp[scratch(rp).file.fd_nr]->filp_vno != vp)
- continue;
- } else if (rp->fp_blocked_on == FP_BLOCKED_ON_PIPE) {
- if (scratch(rp).file.filp == NULL)
- continue;
- if (scratch(rp).file.filp->filp_vno != vp)
+ if (f->filp_vno != vp)
continue;
} else
continue;
* the proc must be restarted so it can try again.
*/
blocked_on = rfp->fp_blocked_on;
- fd_nr = scratch(rfp).file.fd_nr;
+ fd_nr = rfp->fp_fd;
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 {
rfp->fp_blocked_on = FP_BLOCKED_ON_NONE;
- scratch(rfp).file.fd_nr = 0;
+ /* TODO: we could reset rfp->fp_fd to (e.g.) -1 here, but since its
+ * value is not always bounds checked elsewhere, this might do more
+ * harm than good right now.
+ */
if (blocked_on == FP_BLOCKED_ON_POPEN) {
/* process blocked in open or create */
replycode(proc_e, fd_nr);
/* Revive a process suspended on TTY or other device.
* Pretend it wants only what there is.
*/
- scratch(rfp).io.io_nbytes = returned;
+ rfp->fp_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;
case FP_BLOCKED_ON_OTHER:/* process trying to do device I/O (e.g. tty)*/
- fild = scratch(fp).file.fd_nr;
+ fild = fp->fp_fd;
if (fild < 0 || fild >= OPEN_MAX)
panic("file descriptor out-of-range");
f = fp->fp_filp[fild];
#include <fcntl.h>
#include <unistd.h>
#include "file.h"
-#include "scratchpad.h"
#include "vnode.h"
#include "vmnt.h"
if(rw_flag == WRITING) ro = 0;
- scratch(rfp).file.fd_nr = io_fd;
- scratch(rfp).io.io_buffer = io_buf;
- scratch(rfp).io.io_nbytes = io_nbytes;
+ rfp->fp_fd = io_fd;
+ rfp->fp_io_buffer = io_buf;
+ rfp->fp_io_nbytes = io_nbytes;
locktype = rw_flag == WRITING ? VNODE_WRITE : VNODE_READ;
- if ((f = get_filp2(rfp, scratch(rfp).file.fd_nr, locktype)) == NULL)
+ if ((f = get_filp2(rfp, rfp->fp_fd, locktype)) == NULL)
return(err_code);
assert(f->filp_count > 0);
unlock_filp(f);
return(EBADF);
}
- if (scratch(rfp).io.io_nbytes == 0) {
+ if (rfp->fp_io_nbytes == 0) {
unlock_filp(f);
return(0); /* so char special files need not check for 0*/
}
- r = read_write(rfp, rw_flag, f, scratch(rfp).io.io_buffer,
- scratch(rfp).io.io_nbytes, who_e);
+ r = read_write(rfp, rw_flag, f, rfp->fp_io_buffer, rfp->fp_io_nbytes, who_e);
unlock_filp(f);
return(r);
off_t new_pos;
register struct filp *rfilp;
- scratch(fp).file.fd_nr = job_m_in.m_lc_vfs_readwrite.fd;
- scratch(fp).io.io_buffer = job_m_in.m_lc_vfs_readwrite.buf;
- scratch(fp).io.io_nbytes = job_m_in.m_lc_vfs_readwrite.len;
+ fp->fp_fd = job_m_in.m_lc_vfs_readwrite.fd;
+ fp->fp_io_buffer = job_m_in.m_lc_vfs_readwrite.buf;
+ fp->fp_io_nbytes = job_m_in.m_lc_vfs_readwrite.len;
/* Is the file descriptor valid? */
- if ( (rfilp = get_filp(scratch(fp).file.fd_nr, VNODE_READ)) == NULL)
+ if ( (rfilp = get_filp(fp->fp_fd, VNODE_READ)) == NULL)
return(err_code);
if (!(rfilp->filp_mode & R_BIT))
if (r == OK) {
r = req_getdents(rfilp->filp_vno->v_fs_e, rfilp->filp_vno->v_inode_nr,
- rfilp->filp_pos, scratch(fp).io.io_buffer,
- scratch(fp).io.io_nbytes, &new_pos, 0);
+ rfilp->filp_pos, fp->fp_io_buffer, fp->fp_io_nbytes,
+ &new_pos, 0);
if (r > 0) rfilp->filp_pos = new_pos;
}
+++ /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 {
- vir_bytes io_buffer;
- size_t io_nbytes;
- } io;
-} scratchpad[NR_PROCS];
-
-#endif
#include <minix/com.h>
#include "file.h"
#include "lock.h"
-#include "scratchpad.h"
#include "vnode.h"
#include "vmnt.h"