]> Zhao Yanbai Git Server - minix.git/commitdiff
AVFS: Use scratchpad instead of m_in to pass around file descriptors
authorThomas Veerman <thomas@minix3.org>
Wed, 21 Dec 2011 10:52:51 +0000 (10:52 +0000)
committerThomas Veerman <thomas@minix3.org>
Wed, 21 Dec 2011 10:52:51 +0000 (10:52 +0000)
Some code relies on having the file descriptor in m_in.fd. Consequently,
m_in is not only used to provide syscall parameters from user space to
VFS, but also as a global variable to store temporary data within VFS.
This has the ugly side effect that m_in gets overwritten during core
dumping.*

To work around this problem VFS now uses a so called "scratchpad" to
store temporary data that has to be globally accessible. This is a simple
table indexed by process number, just like fproc. The scratchpad allows
us to store the buffer pointer and buffer size for suspended system calls
(i.e., read, write, open, lock) instead of using fproc. This makes fproc
a bit smaller and fproc iterators a bit faster. Moreover, suspension of
processes becomes simpler altogether and suspended operations on pipes
are now less of a special case.

* This patch fixes a bug where due to unexpected m_in overwriting a
coredump would fail, and consequently resources are leaked. The coredump
was triggered with:
$ a() { a; }
$ a

12 files changed:
servers/avfs/device.c
servers/avfs/fproc.h
servers/avfs/glo.h
servers/avfs/lock.c
servers/avfs/main.c
servers/avfs/misc.c
servers/avfs/open.c
servers/avfs/pipe.c
servers/avfs/proto.h
servers/avfs/read.c
servers/avfs/scratchpad.h [new file with mode: 0644]
servers/avfs/table.c

index 21b42dddc3d95122ee433a1c13376310f22594d0..29130df29a02e2242961e6c762f397fdb5e83451 100644 (file)
@@ -32,6 +32,7 @@
 #include <minix/u64.h>
 #include "file.h"
 #include "fproc.h"
+#include "scratchpad.h"
 #include "dmap.h"
 #include <minix/vfsif.h>
 #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];
index ce33ecd527490207571be511be991892d04a87ed..f0ae8419db6029df835085e3946360c3f5075690 100644 (file)
@@ -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 */
index 95a38f02b7390b0458f5270029acfef216f15ca1..0995c144b8d9d96e4ad9609df4a1d0109504cfd0 100644 (file)
@@ -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 */
index 58eddb07754cace04793aaa6dfdcaf2fa5e0855e..36ab59351c56942a642fc85cc06fe057f0b47d5b 100644 (file)
@@ -12,6 +12,7 @@
 #include <unistd.h>
 #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);
   }
 
index 02deb4ce9d0983a660e758e01781c21dafe58b09..85ac294b8bd04d091e6e3df54c47d0e14fe9d7df 100644 (file)
@@ -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;
index 2cb7f3b8bdb2d3c699eb448bb36a0881e2e8858b..08a1afa48f7c578f2ab980b963dc4503108bfd81 100644 (file)
@@ -33,6 +33,7 @@
 #include <sys/svrctl.h>
 #include "file.h"
 #include "fproc.h"
+#include "scratchpad.h"
 #include "dmap.h"
 #include <minix/vfsif.h>
 #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;
index 5358c3171e2f86cb1ad50ac7709bf876eb86fc67..dc8948ca6d7857244a6cff9730dce2f08b08a7bd 100644 (file)
@@ -21,6 +21,7 @@
 #include <minix/u64.h>
 #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);
index 2a841ba19a6a6ea1a36645a666b08f38a2dc09d6..b339f6baf339af573361fb0d39a583f7b2edce54 100644 (file)
@@ -27,6 +27,7 @@
 #include <sys/time.h>
 #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];
index 12db0386ee819cc2aa8bde7f6bf9460096d36d35..327935bd85823b0143550985a678fb2c6cc05ac2 100644 (file)
@@ -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
index 24f3eb6778030d4c37353c90ccf60ee4b2880275..13df38ae0f4e5e278a6fe2e2bc902b54e2b13091 100644 (file)
@@ -17,6 +17,7 @@
 #include <minix/u64.h>
 #include "file.h"
 #include "fproc.h"
+#include "scratchpad.h"
 #include "param.h"
 #include <dirent.h>
 #include <assert.h>
@@ -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 (file)
index 0000000..f33a01c
--- /dev/null
@@ -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
index 792e3ac747db0d0db9536e1ffa0df1c76cb5d3c4..c4a4173bc5a468aa1b2199035c0f33c58841eb6d 100644 (file)
@@ -10,6 +10,7 @@
 #include "file.h"
 #include "fproc.h"
 #include "lock.h"
+#include "scratchpad.h"
 #include "vnode.h"
 #include "vmnt.h"