From: David van Moolenbroek Date: Mon, 10 Aug 2015 22:28:00 +0000 (+0000) Subject: VFS: merge scratchpad into fproc X-Git-Url: http://zhaoyanbai.com/repos/%22http:/www.isc.org/icons/zpipe.c?a=commitdiff_plain;h=bd851af48fd138dabb73c48d0f47ab094eee023a;p=minix.git VFS: merge scratchpad into fproc There is no reason to keep these tightly coupled data structures separate. Moreover, there is no reason to have a union of file descriptor and file pointer, since the second can be derived from the first. The result are somewhat cleaner VFS internals. Change-Id: I854da7d8291177878eecfc3077ef0a9e0cc82aaa --- diff --git a/minix/servers/vfs/device.c b/minix/servers/vfs/device.c index e5a6901c1..53b1e9088 100644 --- a/minix/servers/vfs/device.c +++ b/minix/servers/vfs/device.c @@ -27,7 +27,6 @@ #include #include #include "file.h" -#include "scratchpad.h" #include "dmap.h" #include #include "vnode.h" @@ -357,9 +356,9 @@ static int cdev_clone(dev_t dev, devminor_t new_minor) } 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; @@ -370,7 +369,7 @@ static int cdev_clone(dev_t dev, devminor_t new_minor) 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; } @@ -513,11 +512,11 @@ int do_ioctl(void) 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)) { diff --git a/minix/servers/vfs/fproc.h b/minix/servers/vfs/fproc.h index a303c357e..51c0fffa2 100644 --- a/minix/servers/vfs/fproc.h +++ b/minix/servers/vfs/fproc.h @@ -31,6 +31,10 @@ EXTERN struct fproc { 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 */ diff --git a/minix/servers/vfs/glo.h b/minix/servers/vfs/glo.h index 1138d9646..3fbdb05ea 100644 --- a/minix/servers/vfs/glo.h +++ b/minix/servers/vfs/glo.h @@ -31,7 +31,6 @@ EXTERN message m_in; /* the input message itself */ # 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 */ diff --git a/minix/servers/vfs/link.c b/minix/servers/vfs/link.c index d4aed5128..9d699a03c 100644 --- a/minix/servers/vfs/link.c +++ b/minix/servers/vfs/link.c @@ -22,7 +22,6 @@ #include "file.h" #include "path.h" #include "vnode.h" -#include "scratchpad.h" /*===========================================================================* * do_link * @@ -333,13 +332,13 @@ int do_ftruncate(void) 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; diff --git a/minix/servers/vfs/lock.c b/minix/servers/vfs/lock.c index 4b7724670..b7aefda3a 100644 --- a/minix/servers/vfs/lock.c +++ b/minix/servers/vfs/lock.c @@ -11,7 +11,6 @@ #include #include #include "file.h" -#include "scratchpad.h" #include "lock.h" #include "vnode.h" @@ -31,7 +30,7 @@ int req; /* either F_SETLK or F_SETLKW */ 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); @@ -142,7 +141,7 @@ int req; /* either F_SETLK or F_SETLKW */ /* 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); } diff --git a/minix/servers/vfs/main.c b/minix/servers/vfs/main.c index 4dac592c2..44fd1d451 100644 --- a/minix/servers/vfs/main.c +++ b/minix/servers/vfs/main.c @@ -26,7 +26,6 @@ #include #include #include "file.h" -#include "scratchpad.h" #include "vmnt.h" #include "vnode.h" @@ -211,15 +210,14 @@ static void do_pending_pipe(void) 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. @@ -834,15 +832,15 @@ struct fproc *rfp; 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: diff --git a/minix/servers/vfs/misc.c b/minix/servers/vfs/misc.c index 9e426ce0e..876686a9b 100644 --- a/minix/servers/vfs/misc.c +++ b/minix/servers/vfs/misc.c @@ -33,7 +33,6 @@ #include #include #include "file.h" -#include "scratchpad.h" #include #include "vnode.h" #include "vmnt.h" @@ -103,15 +102,15 @@ int do_fcntl(void) 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) { @@ -132,16 +131,16 @@ int do_fcntl(void) 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: @@ -174,7 +173,7 @@ int do_fcntl(void) 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)); } @@ -284,9 +283,9 @@ int do_fsync(void) 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; @@ -885,8 +884,8 @@ int pm_dumpcore(int csig, vir_bytes exe_name) 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(); diff --git a/minix/servers/vfs/open.c b/minix/servers/vfs/open.c index 740b89964..1fbdbaf87 100644 --- a/minix/servers/vfs/open.c +++ b/minix/servers/vfs/open.c @@ -18,7 +18,6 @@ #include #include #include "file.h" -#include "scratchpad.h" #include "lock.h" #include #include @@ -100,8 +99,7 @@ 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(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); @@ -132,12 +130,12 @@ 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[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) { @@ -243,7 +241,7 @@ 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[scratch(fp).file.fd_nr] = filp2; + fp->fp_filp[fp->fp_fd] = filp2; filp2->filp_count++; filp2->filp_vno = vp; filp2->filp_flags = oflags; @@ -271,13 +269,13 @@ 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[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); diff --git a/minix/servers/vfs/pipe.c b/minix/servers/vfs/pipe.c index b4999562d..860c09dd4 100644 --- a/minix/servers/vfs/pipe.c +++ b/minix/servers/vfs/pipe.c @@ -27,7 +27,6 @@ #include #include #include "file.h" -#include "scratchpad.h" #include #include "vnode.h" #include "vmnt.h" @@ -334,9 +333,16 @@ size_t size; * 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); } @@ -409,17 +415,13 @@ int count; /* max number of processes to release */ */ 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; @@ -459,14 +461,17 @@ void revive(endpoint_t proc_e, int returned) * 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); @@ -476,7 +481,7 @@ void revive(endpoint_t proc_e, int returned) /* 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. */ @@ -545,7 +550,7 @@ void unpause(void) 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]; diff --git a/minix/servers/vfs/read.c b/minix/servers/vfs/read.c index 7cbe64a80..5f0a5e783 100644 --- a/minix/servers/vfs/read.c +++ b/minix/servers/vfs/read.c @@ -20,7 +20,6 @@ #include #include #include "file.h" -#include "scratchpad.h" #include "vnode.h" #include "vmnt.h" @@ -92,12 +91,12 @@ int actual_read_write_peek(struct fproc *rfp, int rw_flag, int io_fd, 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); @@ -106,13 +105,12 @@ int actual_read_write_peek(struct fproc *rfp, int rw_flag, int io_fd, 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); @@ -274,12 +272,12 @@ int do_getdents(void) 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)) @@ -289,8 +287,8 @@ int do_getdents(void) 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; } diff --git a/minix/servers/vfs/scratchpad.h b/minix/servers/vfs/scratchpad.h deleted file mode 100644 index ff31a5ce1..000000000 --- a/minix/servers/vfs/scratchpad.h +++ /dev/null @@ -1,18 +0,0 @@ -#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 diff --git a/minix/servers/vfs/table.c b/minix/servers/vfs/table.c index 8cec7c177..78078ed16 100644 --- a/minix/servers/vfs/table.c +++ b/minix/servers/vfs/table.c @@ -9,7 +9,6 @@ #include #include "file.h" #include "lock.h" -#include "scratchpad.h" #include "vnode.h" #include "vmnt.h"