]> Zhao Yanbai Git Server - minix.git/commitdiff
VFS: remove support for sync char driver protocol 48/948/2
authorDavid van Moolenbroek <david@minix3.org>
Fri, 30 Aug 2013 11:33:56 +0000 (13:33 +0200)
committerLionel Sambuc <lionel@minix3.org>
Tue, 18 Feb 2014 10:25:03 +0000 (11:25 +0100)
Change-Id: I57cc870a053b813b3a3fc45da46606ea84fe4cb1

servers/vfs/const.h
servers/vfs/device.c
servers/vfs/dmap.c
servers/vfs/main.c
servers/vfs/pipe.c
servers/vfs/proto.h
servers/vfs/read.c
servers/vfs/select.c

index b587f0e5fd3f9e3e996bafe33fbf6a67d88743c1..d8c2f5c41a16708df0e28246ca17577ab9667c10 100644 (file)
                                 */
 #define FSTYPE_MAX     VFS_NAMELEN     /* maximum file system type size */
 
-/* Args to dev_io */
-#define VFS_DEV_READ   2001
-#define        VFS_DEV_WRITE   2002
-#define VFS_DEV_IOCTL  2005
-#define VFS_DEV_SELECT 2006
-
-#define dev_style_asyn(n)      (TRUE)
-
 #endif
index 759cc6896e24bf9f1574e3b4b6fcd74808601700..dffa310f97d2b31790d42221fee9f571274bbe48 100644 (file)
@@ -8,8 +8,8 @@
  *   bdev_open:  open a block device
  *   bdev_close: close a block device
  *   dev_io:    FS does a read or write on a device
- *   gen_opcl:   generic call to a task to perform an open/close
- *   gen_io:     generic call to a task to perform an I/O operation
+ *   gen_opcl:   generic call to a character driver to perform an open/close
+ *   gen_io:     generic call to a character driver to initiate I/O
  *   no_dev:     open/close processing for devices that don't exist
  *   no_dev_io:  i/o processing for devices that don't exist
  *   tty_opcl:   perform tty-specific processing for open/close
@@ -17,6 +17,9 @@
  *   ctty_io:    perform controlling-tty-specific processing for I/O
  *   pm_setsid:         perform VFS's side of setsid system call
  *   do_ioctl:  perform the IOCTL system call
+ *   task_reply: process the result of a character driver I/O request
+ *   dev_select: initiate a select call on a device
+ *   dev_cancel: cancel an I/O request, blocking until it has been cancelled
  */
 
 #include "fs.h"
 #include "vmnt.h"
 #include "param.h"
 
+static int block_io(endpoint_t driver_e, message *mess_ptr);
+static cp_grant_id_t make_grant(endpoint_t driver_e, endpoint_t user_e, int op,
+       void *buf, size_t size);
 static void restart_reopen(int major);
-static int safe_io_conversion(endpoint_t, cp_grant_id_t *, int *,
-       endpoint_t *, void **, size_t, u32_t *);
 
 static int dummyproc;
 
@@ -157,10 +161,9 @@ static int bdev_ioctl(dev_t dev, endpoint_t proc_e, int req, void *buf)
 {
 /* Perform an I/O control operation on a block device. */
   struct dmap *dp;
-  u32_t dummy;
   cp_grant_id_t gid;
   message dev_mess;
-  int op, major_dev, minor_dev;
+  int major_dev, minor_dev;
 
   major_dev = major(dev);
   minor_dev = minor(dev);
@@ -173,9 +176,7 @@ static int bdev_ioctl(dev_t dev, endpoint_t proc_e, int req, void *buf)
   }
 
   /* Set up a grant if necessary. */
-  op = VFS_DEV_IOCTL;
-  (void) safe_io_conversion(dp->dmap_driver, &gid, &op, &proc_e, &buf, req,
-       &dummy);
+  gid = make_grant(dp->dmap_driver, proc_e, BDEV_IOCTL, buf, req);
 
   /* Set up the message passed to the task. */
   memset(&dev_mess, 0, sizeof(dev_mess));
@@ -187,7 +188,7 @@ static int bdev_ioctl(dev_t dev, endpoint_t proc_e, int req, void *buf)
   dev_mess.BDEV_ID = 0;
 
   /* Call the task. */
-  gen_io(dp->dmap_driver, &dev_mess);
+  block_io(dp->dmap_driver, &dev_mess);
 
   /* Clean up. */
   if (GRANT_VALID(gid)) cpf_revoke(gid);
@@ -205,7 +206,7 @@ static int bdev_ioctl(dev_t dev, endpoint_t proc_e, int req, void *buf)
 /*===========================================================================*
  *                             find_suspended_ep                            *
  *===========================================================================*/
-endpoint_t find_suspended_ep(endpoint_t driver, cp_grant_id_t g)
+static endpoint_t find_suspended_ep(endpoint_t driver, cp_grant_id_t g)
 {
 /* A process is suspended on a driver for which VFS issued a grant. Find out
  * which process it was.
@@ -215,9 +216,11 @@ endpoint_t find_suspended_ep(endpoint_t driver, cp_grant_id_t g)
        if(rfp->fp_pid == PID_FREE)
                continue;
 
-       if(rfp->fp_blocked_on == FP_BLOCKED_ON_OTHER &&
-          rfp->fp_task == driver && rfp->fp_grant == g)
+       if (rfp->fp_task == driver && rfp->fp_grant == g) {
+               assert(!fp_is_blocked(rfp) ||
+                       rfp->fp_blocked_on == FP_BLOCKED_ON_OTHER);
                return(rfp->fp_endpoint);
+       }
   }
 
   return(NONE);
@@ -225,40 +228,29 @@ endpoint_t find_suspended_ep(endpoint_t driver, cp_grant_id_t g)
 
 
 /*===========================================================================*
- *                             safe_io_conversion                           *
+ *                             make_grant                                   *
  *===========================================================================*/
-static int safe_io_conversion(driver, gid, op, io_ept, buf, bytes, pos_lo)
-endpoint_t driver;
-cp_grant_id_t *gid;
-int *op;
-endpoint_t *io_ept;
-void **buf;
-size_t bytes;
-u32_t *pos_lo;
+static cp_grant_id_t make_grant(endpoint_t driver_e, endpoint_t user_e, int op,
+       void *buf, size_t bytes)
 {
-/* Convert operation to the 'safe' variant (i.e., grant based) if applicable.
- * If no copying of data is involved, there is also no need to convert. */
-
-  int access = 0;
+/* Create a magic grant for the given operation and buffer. */
+  cp_grant_id_t gid;
+  int access;
   size_t size;
 
-  *gid = GRANT_INVALID;                /* Grant to buffer */
-
-  switch(*op) {
-    case VFS_DEV_READ:
-    case VFS_DEV_WRITE:
-       /* Change to safe op. */
-       *op = (*op == VFS_DEV_READ) ? DEV_READ_S : DEV_WRITE_S;
-       *gid = cpf_grant_magic(driver, *io_ept, (vir_bytes) *buf, bytes,
-                              *op == DEV_READ_S ? CPF_WRITE : CPF_READ);
-       if (*gid < 0)
-               panic("VFS: cpf_grant_magic of READ/WRITE buffer failed");
+  switch (op) {
+  case DEV_READ_S:
+  case DEV_WRITE_S:
+       gid = cpf_grant_magic(driver_e, user_e, (vir_bytes) buf, bytes,
+               op == DEV_READ_S ? CPF_WRITE : CPF_READ);
        break;
-    case VFS_DEV_IOCTL:
-       *pos_lo = *io_ept; /* Old endpoint in POSITION field. */
-       *op = DEV_IOCTL_S;
+
+  case DEV_IOCTL_S:
+  case BDEV_IOCTL:
        /* For IOCTLs, the bytes parameter encodes requested access method
-        * and buffer size */
+        * and buffer size
+        */
+       access = 0;
        if(_MINIX_IOCTL_IOR(bytes)) access |= CPF_WRITE;
        if(_MINIX_IOCTL_IOW(bytes)) access |= CPF_READ;
        if(_MINIX_IOCTL_BIG(bytes))
@@ -269,39 +261,27 @@ u32_t *pos_lo;
        /* Grant access to the buffer even if no I/O happens with the ioctl, in
         * order to disambiguate requests with DEV_IOCTL_S.
         */
-       *gid = cpf_grant_magic(driver, *io_ept, (vir_bytes) *buf, size, access);
-       if (*gid < 0)
-               panic("VFS: cpf_grant_magic IOCTL buffer failed");
-
-       break;
-    case VFS_DEV_SELECT:
-       *op = DEV_SELECT;
+       gid = cpf_grant_magic(driver_e, user_e, (vir_bytes) buf, size, access);
        break;
-    default:
-       panic("VFS: unknown operation %d for safe I/O conversion", *op);
-  }
 
-  /* If we have converted to a safe operation, I/O endpoint becomes VFS if it
-   * wasn't already.
-   */
-  if(GRANT_VALID(*gid)) {
-       *io_ept = VFS_PROC_NR;
-       return(1);
+  default:
+       panic("VFS: unknown operation %d", op);
   }
 
-  /* Not converted to a safe operation (because there is no copying involved in
-   * this operation).
-   */
-  return(0);
+  if (!GRANT_VALID(gid))
+       panic("VFS: cpf_grant_magic failed");
+
+  return gid;
 }
 
+
 /*===========================================================================*
  *                             dev_io                                       *
  *===========================================================================*/
 int dev_io(
-  int op,                      /* DEV_READ, DEV_WRITE, DEV_IOCTL, etc. */
+  int op,                      /* DEV_READ_S, DEV_WRITE_S, or DEV_IOCTL_S */
   dev_t dev,                   /* major-minor device number */
-  endpoint_t proc_e,                   /* in whose address space is buf? */
+  endpoint_t proc_e,           /* in whose address space is buf? */
   void *buf,                   /* virtual address of the buffer */
   off_t pos,                   /* byte position */
   size_t bytes,                        /* how many bytes to transfer */
@@ -309,22 +289,17 @@ int dev_io(
   int suspend_reopen           /* Just suspend the process */
 )
 {
-/* Read from or write to a device.  The parameter 'dev' tells which one. */
+/* Initiate a read, write, or ioctl to a device. */
   struct dmap *dp;
-  u32_t pos_lo, pos_high;
   message dev_mess;
-  cp_grant_id_t gid = GRANT_INVALID;
-  int safe, minor_dev, major_dev;
-  void *buf_used;
-  endpoint_t ioproc;
-  int ret, is_asyn;
-
-  pos_lo = ex64lo(pos);
-  pos_high = ex64hi(pos);
-  major_dev = major(dev);
-  minor_dev = minor(dev);
+  cp_grant_id_t gid;
+  int r, minor_dev, major_dev;
+
+  assert(op == DEV_READ_S || op == DEV_WRITE_S || op == DEV_IOCTL_S);
 
   /* Determine task dmap. */
+  major_dev = major(dev);
+  minor_dev = minor(dev);
   dp = &dmap[major_dev];
 
   /* See if driver is roughly valid. */
@@ -345,77 +320,42 @@ int dev_io(
        return(ENXIO);
   }
 
-  /* By default, these are right. */
-  dev_mess.USER_ENDPT = proc_e;
-  dev_mess.ADDRESS  = buf;
-
-  /* Convert DEV_* to DEV_*_S variants. */
-  buf_used = buf;
-  safe = safe_io_conversion(dp->dmap_driver, &gid, &op,
-                           (endpoint_t *) &dev_mess.USER_ENDPT, &buf_used,
-                           bytes, &pos_lo);
+  /* Create a grant for the buffer provided by the user process. */
+  gid = make_grant(dp->dmap_driver, proc_e, op, buf, bytes);
 
-  is_asyn = dev_style_asyn(dp->dmap_style);
-
-  /* If the safe conversion was done, set the IO_GRANT to
-   * the grant id.
-   */
-  if(safe) dev_mess.IO_GRANT = (char *) gid;
-
-  /* Set up the rest of the message passed to task. */
+  /* Set up the rest of the message that will be sent to the driver. */
   dev_mess.m_type   = op;
   dev_mess.DEVICE   = minor_dev;
-  dev_mess.POSITION = pos_lo;
-  dev_mess.COUNT    = bytes;
-  dev_mess.HIGHPOS  = pos_high;
+  if (op == DEV_IOCTL_S) {
+       dev_mess.REQUEST  = bytes;
+       dev_mess.POSITION = proc_e;
+  } else {
+       dev_mess.POSITION = ex64lo(pos);
+       dev_mess.COUNT    = bytes;
+  }
+  dev_mess.HIGHPOS  = ex64hi(pos);
+  dev_mess.USER_ENDPT = VFS_PROC_NR;
+  dev_mess.IO_GRANT = (void *) gid;
   dev_mess.FLAGS    = 0;
-
   if (flags & O_NONBLOCK)
          dev_mess.FLAGS |= FLG_OP_NONBLOCK;
 
-  /* This will be used if the i/o is suspended. */
-  ioproc = dev_mess.USER_ENDPT;
-
-  /* Call the task. */
-  (*dp->dmap_io)(dp->dmap_driver, &dev_mess);
-
-  if(dp->dmap_driver == NONE) {
-       /* Driver has vanished. */
-       printf("VFS: driver gone?!\n");
-       if(safe) cpf_revoke(gid);
-       return(EIO);
-  }
-
-  ret = dev_mess.REP_STATUS;
-
-  /* Legacy support: translate EINTR to EAGAIN for nonblocking calls. */
-  if (ret == EINTR && (flags & O_NONBLOCK))
-       ret = EAGAIN;
-
-  /* Task has completed.  See if call completed. */
-  if (ret == SUSPEND) {
-       if ((flags & O_NONBLOCK) && !is_asyn) {
-               printf("VFS: sync char driver %u sent SUSPEND on NONBLOCK\n",
-                       dp->dmap_driver);
-               /* We'd cancel, but the other side won't play ball anyway.. */
-       }
+  /* Send the request to the driver. */
+  r = (*dp->dmap_io)(dp->dmap_driver, &dev_mess);
 
-       /* select() will do suspending itself. */
-       if(op != DEV_SELECT) {
-               /* Suspend user. */
-               wait_for(dp->dmap_driver);
-       }
-       assert(!GRANT_VALID(fp->fp_grant));
-       fp->fp_grant = gid;     /* revoke this when unsuspended. */
-       fp->fp_ioproc = ioproc;
+  if (r != OK) {
+       cpf_revoke(gid);
 
-       return(SUSPEND);
+       return r;
   }
 
-  /* No suspend, or cancelled suspend, so I/O is over and can be cleaned up. */
-  if(safe) cpf_revoke(gid);
+  /* Suspend the calling process until a reply arrives. */
+  wait_for(dp->dmap_driver);
+  assert(!GRANT_VALID(fp->fp_grant));
+  fp->fp_grant = gid;  /* revoke this when unsuspended. */
+  fp->fp_ioproc = VFS_PROC_NR;
 
-  return ret;
+  return SUSPEND;
 }
 
 /*===========================================================================*
@@ -450,7 +390,7 @@ int gen_opcl(
        dev_mess.BDEV_ID = 0;
 
        /* Call the task. */
-       r = gen_io(dp->dmap_driver, &dev_mess);
+       r = block_io(dp->dmap_driver, &dev_mess);
   } else {
        dev_mess.m_type = op;
        dev_mess.DEVICE = minor_dev;
@@ -463,7 +403,7 @@ int gen_opcl(
 
   if (r != OK) return(r);
 
-  if (op == DEV_OPEN && dev_style_asyn(dp->dmap_style)) {
+  if (op == DEV_OPEN) {
        fp->fp_task = dp->dmap_driver;
        self->w_task = dp->dmap_driver;
        self->w_drv_sendrec = &dev_mess;
@@ -593,7 +533,7 @@ int do_ioctl(message *UNUSED(m_out))
        if (S_ISBLK(vp->v_mode))
                r = bdev_ioctl(dev, who_e, ioctlrequest, argx);
        else
-               r = dev_io(VFS_DEV_IOCTL, dev, who_e, argx, 0,
+               r = dev_io(DEV_IOCTL_S, dev, who_e, argx, 0,
                           ioctlrequest, f->filp_flags, suspend_reopen);
   }
 
@@ -604,31 +544,100 @@ int do_ioctl(message *UNUSED(m_out))
 
 
 /*===========================================================================*
- *                             gen_io                                       *
+ *                             dev_select                                   *
+ *===========================================================================*/
+int dev_select(dev_t dev, int ops)
+{
+/* Initiate a select call on a device. Return OK iff the request was sent. */
+  int major_dev, minor_dev;
+  message dev_mess;
+  struct dmap *dp;
+
+  major_dev = major(dev);
+  minor_dev = minor(dev);
+  dp = &dmap[major_dev];
+
+  if (dp->dmap_driver == NONE) return ENXIO;
+
+  memset(&dev_mess, 0, sizeof(dev_mess));
+
+  dev_mess.m_type = DEV_SELECT;
+  dev_mess.DEV_MINOR = minor_dev;
+  dev_mess.DEV_SEL_OPS = ops;
+
+  /* Call the task. */
+  return (*dp->dmap_io)(dp->dmap_driver, &dev_mess);
+}
+
+
+/*===========================================================================*
+ *                             dev_cancel                                   *
  *===========================================================================*/
-int gen_io(driver_e, mess_ptr)
-endpoint_t driver_e;           /* which endpoint to call */
-message *mess_ptr;             /* pointer to message for task */
+int dev_cancel(dev_t dev)
 {
-/* All file system I/O ultimately comes down to I/O on major/minor device
- * pairs.  These lead to calls on the following routines via the dmap table.
+/* Cancel an I/O request, blocking until it has been cancelled. */
+  int r, minor_dev, major_dev;
+  message dev_mess;
+  struct dmap *dp;
+
+  major_dev = major(dev);
+  minor_dev = minor(dev);
+  dp = &dmap[major_dev];
+
+  memset(&dev_mess, 0, sizeof(dev_mess));
+
+  dev_mess.m_type = CANCEL;
+  dev_mess.DEVICE = minor_dev;
+  dev_mess.USER_ENDPT = fp->fp_ioproc;
+  dev_mess.IO_GRANT = (char *) fp->fp_grant;
+
+  /* Tell driver R or W. Mode is from current call, not open. */
+  /* FIXME: ioctls also pass through here! */
+  dev_mess.COUNT = fp->fp_block_callnr == READ ? R_BIT : W_BIT;
+
+  r = (*dp->dmap_io)(fp->fp_task, &dev_mess);
+  if (r != OK) return r; /* ctty_io returned an error? should be impossible */
+
+  /* Suspend this thread until we have received the response. */
+  fp->fp_task = dp->dmap_driver;
+  self->w_task = dp->dmap_driver;
+  self->w_drv_sendrec = &dev_mess;
+
+  worker_wait();
+
+  self->w_task = NONE;
+  self->w_drv_sendrec = NULL;
+
+  /* Clean up and return the result (note: the request may have completed). */
+  if (GRANT_VALID(fp->fp_grant)) {
+       (void) cpf_revoke(fp->fp_grant);
+       fp->fp_grant = GRANT_INVALID;
+  }
+
+  r = dev_mess.REP_STATUS;
+  return (r == EAGAIN) ? EINTR : r;
+}
+
+
+/*===========================================================================*
+ *                             block_io                                     *
+ *===========================================================================*/
+static int block_io(endpoint_t driver_e, message *mess_ptr)
+{
+/* Perform I/O on a block device. The current thread is suspended until a reply
+ * comes in from the driver.
  */
-  int r, status = OK, proc_e = NONE, is_bdev, retry_count;
+  int r, status, retry_count;
   message mess_retry;
 
-  is_bdev = IS_BDEV_RQ(mess_ptr->m_type);
+  assert(IS_BDEV_RQ(mess_ptr->m_type));
   mess_retry = *mess_ptr;
   retry_count = 0;
 
-  if (!is_bdev) proc_e = mess_ptr->USER_ENDPT;
-
   do {
        r = drv_sendrec(driver_e, mess_ptr);
        if (r == OK) {
-               if (is_bdev)
-                       status = mess_ptr->BDEV_STATUS;
-               else
-                       status = mess_ptr->REP_STATUS;
+               status = mess_ptr->BDEV_STATUS;
                if (status == ERESTART) {
                        r = EDEADEPT;
                        *mess_ptr = mess_retry;
@@ -652,39 +661,26 @@ message *mess_ptr;                /* pointer to message for task */
                printf("VFS: ELOCKED talking to %d\n", driver_e);
                return(r);
        }
-       panic("call_task: can't send/receive: %d", r);
+       panic("block_io: can't send/receive: %d", r);
   }
 
-  /* Did the process we did the sendrec() for get a result? */
-  if (!is_bdev && mess_ptr->REP_ENDPT != proc_e && mess_ptr->m_type != EIO) {
-       printf("VFS: strange device reply from %d, type = %d, "
-               "proc = %d (not %d) (2) ignored\n", mess_ptr->m_source,
-               mess_ptr->m_type, proc_e, mess_ptr->REP_ENDPT);
-
-       return(EIO);
-  } else if (!IS_DRV_REPLY(mess_ptr->m_type))
-       return(EIO);
-
   return(OK);
 }
 
 
 /*===========================================================================*
- *                             asyn_io                                      *
+ *                             gen_io                                       *
  *===========================================================================*/
-int asyn_io(endpoint_t drv_e, message *mess_ptr)
+int gen_io(endpoint_t drv_e, message *mess_ptr)
 {
-/* All file system I/O ultimately comes down to I/O on major/minor device
- * pairs. These lead to calls on the following routines via the dmap table.
- */
-
+/* Initiate I/O to a character driver. Do not wait for the reply. */
   int r;
 
   assert(!IS_BDEV_RQ(mess_ptr->m_type));
 
   r = asynsend3(drv_e, mess_ptr, AMF_NOREPLY);
 
-  if (r != OK) panic("VFS: asynsend in asyn_io failed: %d", r);
+  if (r != OK) panic("VFS: asynsend in gen_io failed: %d", r);
 
   /* Fake a SUSPEND */
   mess_ptr->REP_STATUS = SUSPEND;
@@ -709,7 +705,7 @@ int ctty_io(
 
   if (fp->fp_tty == 0) {
        /* No controlling tty present anymore, return an I/O error. */
-       mess_ptr->REP_STATUS = EIO;
+       return(EIO);
   } else {
        /* Substitute the controlling terminal device. */
        dp = &dmap[major(fp->fp_tty)];
@@ -725,10 +721,8 @@ int ctty_io(
                return(EIO);
        }
 
-       (*dp->dmap_io)(dp->dmap_driver, mess_ptr);
+       return (*dp->dmap_io)(dp->dmap_driver, mess_ptr);
   }
-
-  return(OK);
 }
 
 
@@ -800,8 +794,8 @@ int clone_opcl(
   r = (*dp->dmap_io)(dp->dmap_driver, &dev_mess);
   if (r != OK) return(r);
 
-  if (op == DEV_OPEN && dev_style_asyn(dp->dmap_style)) {
-       /* Wait for reply when driver is asynchronous */
+  if (op == DEV_OPEN) {
+       /* Wait for the reply. */
        fp->fp_task = dp->dmap_driver;
        self->w_task = dp->dmap_driver;
        self->w_drv_sendrec = &dev_mess;
@@ -968,6 +962,50 @@ void open_reply(void)
   worker_signal(wp);   /* Continue open */
 }
 
+
+/*===========================================================================*
+ *                             task_reply                                   *
+ *===========================================================================*/
+void task_reply(void)
+{
+/* A character driver has results for a read, write, or ioctl call. */
+  struct fproc *rfp;
+  struct worker_thread *wp;
+  endpoint_t proc_e;
+  int slot;
+
+  proc_e = job_m_in.REP_ENDPT;
+  if (proc_e == VFS_PROC_NR)
+       proc_e = find_suspended_ep(job_m_in.m_source, job_m_in.REP_IO_GRANT);
+  else
+       printf("VFS: endpoint %u from %u is not VFS\n",
+               proc_e, job_m_in.m_source);
+
+  if (proc_e == NONE) {
+       printf("VFS: proc with grant %d from %d not found\n",
+               job_m_in.REP_IO_GRANT, job_m_in.m_source);
+  } else if (job_m_in.REP_STATUS == SUSPEND) {
+       printf("VFS: got SUSPEND on DEV_REVIVE: not reviving proc\n");
+  } else {
+       /* If there is a thread active for this process, we assume that this
+        * thread aims to cancel the ongoing operation. In that case, wake up
+        * the thread to let it finish unpausing the process. Otherwise, revive
+        * the process as usual.
+        */
+       if (isokendpt(proc_e, &slot) != OK) return;
+       rfp = &fproc[slot];
+       wp = worker_get(rfp->fp_wtid);
+       if (wp != NULL && wp->w_task == who_e) {
+               assert(!fp_is_blocked(rfp));
+               *wp->w_drv_sendrec = job_m_in;
+               worker_signal(wp);      /* Continue cancel */
+       } else {
+               revive(proc_e, job_m_in.REP_STATUS);
+       }
+  }
+}
+
+
 /*===========================================================================*
  *                             dev_reply                                    *
  *===========================================================================*/
index 3111c95b24d4906bd328825a713dafea9cbc542d..c6491fde8465f58ad8861d660714dba74be77d1f 100644 (file)
@@ -180,11 +180,11 @@ int flags;                        /* device flags */
   switch (style) {
     case STYLE_DEV:
        dp->dmap_opcl = gen_opcl;
-       dp->dmap_io = asyn_io;
+       dp->dmap_io = gen_io;
        break;
     case STYLE_TTY:
        dp->dmap_opcl = tty_opcl;
-       dp->dmap_io = asyn_io;
+       dp->dmap_io = gen_io;
        break;
     case STYLE_CTTY:
        dp->dmap_opcl = ctty_opcl;
@@ -192,7 +192,7 @@ int flags;                  /* device flags */
        break;
     case STYLE_CLONE:
        dp->dmap_opcl = clone_opcl;
-       dp->dmap_io = asyn_io;
+       dp->dmap_io = gen_io;
        break;
     default:
        return(EINVAL);
index 41997836bc8d7eaf63632dd74576bf9459ba3c9b..8a92df4c85ead55f718ef188017cf46e71bd858a 100644 (file)
@@ -40,7 +40,7 @@ EXTERN unsigned long calls_stats[NCALLS];
 #endif
 
 /* Thread related prototypes */
-static void *do_async_dev_result(void *arg);
+static void *do_char_dev_result(void *arg);
 static void *do_control_msgs(void *arg);
 static void *do_fs_reply(struct job *job);
 static void *do_work(void *arg);
@@ -137,9 +137,8 @@ int main(void)
 
                dp = get_dmap(who_e);
                if (dp != NULL) {
-                       if (!IS_BDEV_RS(call_nr) &&
-                           dev_style_asyn(dp->dmap_style)) {
-                               handle_work(do_async_dev_result);
+                       if (!IS_BDEV_RS(call_nr)) {
+                               handle_work(do_char_dev_result);
 
                        } else {
                                if (dp->dmap_servicing == NONE) {
@@ -211,31 +210,17 @@ static void handle_work(void *(*func)(void *arg))
 }
 
 /*===========================================================================*
- *                            do_async_dev_result                           *
+ *                            do_char_dev_result                            *
  *===========================================================================*/
-static void *do_async_dev_result(void *arg)
+static void *do_char_dev_result(void *arg)
 {
-  endpoint_t endpt;
   struct job my_job;
 
   my_job = *((struct job *) arg);
   fp = my_job.j_fp;
 
-  /* An asynchronous character driver has results for us */
-  if (job_call_nr == DEV_REVIVE) {
-       endpt = job_m_in.REP_ENDPT;
-       if (endpt == VFS_PROC_NR)
-               endpt = find_suspended_ep(job_m_in.m_source,
-                                         job_m_in.REP_IO_GRANT);
-
-       if (endpt == NONE) {
-               printf("VFS: proc with grant %d from %d not found\n",
-                       job_m_in.REP_IO_GRANT, job_m_in.m_source);
-       } else if (job_m_in.REP_STATUS == SUSPEND) {
-               printf("VFS: got SUSPEND on DEV_REVIVE: not reviving proc\n");
-       } else
-               revive(endpt, job_m_in.REP_STATUS);
-  }
+  /* A character driver has results for us. */
+  if (job_call_nr == DEV_REVIVE) task_reply();
   else if (job_call_nr == DEV_OPEN_REPL) open_reply();
   else if (job_call_nr == DEV_REOPEN_REPL) reopen_reply();
   else if (job_call_nr == DEV_CLOSE_REPL) close_reply();
index c0c896f93fc6e43f88b4f9b368714c46f630df62..50f6ddb3e368f82ce03f10b9e1c4ea3b985d9d72 100644 (file)
@@ -529,10 +529,9 @@ void unpause(endpoint_t proc_e)
  */
 
   register struct fproc *rfp, *org_fp;
-  int slot, blocked_on, fild, status = EINTR, major_dev, minor_dev;
+  int slot, blocked_on, fild, status = EINTR;
   struct filp *f;
   dev_t dev;
-  message mess;
   int wasreviving = 0;
 
   if (isokendpt(proc_e, &slot) != OK) {
@@ -584,31 +583,12 @@ void unpause(endpoint_t proc_e)
                                rfp->fp_endpoint, fild);
                }
                dev = (dev_t) f->filp_vno->v_sdev;      /* device hung on */
-               major_dev = major(dev);
-               minor_dev = minor(dev);
-               mess.DEVICE = minor_dev;
-               mess.USER_ENDPT = rfp->fp_ioproc;
-               mess.IO_GRANT = (char *) rfp->fp_grant;
-
-               /* Tell kernel R or W. Mode is from current call, not open. */
-               mess.COUNT = rfp->fp_block_callnr == READ ? R_BIT : W_BIT;
-               mess.m_type = CANCEL;
 
                org_fp = fp;
                fp = rfp;       /* hack - ctty_io uses fp */
-               (*dmap[major_dev].dmap_io)(rfp->fp_task, &mess);
+               status = dev_cancel(dev);
                fp = org_fp;
-               status = mess.REP_STATUS;
-               if (status == SUSPEND)
-                       return;         /* Process will be revived at a
-                                        * later time.
-                                        */
 
-               if (status == EAGAIN) status = EINTR;
-               if (GRANT_VALID(rfp->fp_grant)) {
-                       (void) cpf_revoke(rfp->fp_grant);
-                       rfp->fp_grant = GRANT_INVALID;
-               }
                break;
        default :
                panic("VFS: unknown block reason: %d", blocked_on);
index ff0124f9e46da0435edad67cf9504a8b91b4be49..8f1d16089987b9456331d9ad758ceba6fc0bfaea 100644 (file)
@@ -38,8 +38,7 @@ int bdev_close(dev_t dev);
 int dev_io(int op, dev_t dev, endpoint_t proc_e, void *buf, off_t pos,
        size_t bytes, int flags, int suspend_reopen);
 int gen_opcl(int op, dev_t dev, endpoint_t task_nr, int flags);
-int gen_io(endpoint_t driver_e, message *mess_ptr);
-int asyn_io(endpoint_t drv_e, message *mess_ptr);
+int gen_io(endpoint_t drv_e, message *mess_ptr);
 int no_dev(int op, dev_t dev, endpoint_t proc, int flags);
 int no_dev_io(endpoint_t, message *);
 int tty_opcl(int op, dev_t dev, endpoint_t proc, int flags);
@@ -47,12 +46,14 @@ int ctty_opcl(int op, dev_t dev, endpoint_t proc, int flags);
 int clone_opcl(int op, dev_t dev, endpoint_t proc, int flags);
 int ctty_io(endpoint_t task_nr, message *mess_ptr);
 int do_ioctl(message *m_out);
+int dev_select(dev_t dev, int ops);
+int dev_cancel(dev_t dev);
 void pm_setsid(endpoint_t proc_e);
 void bdev_up(int major);
 void cdev_up(int major);
-endpoint_t find_suspended_ep(endpoint_t driver, cp_grant_id_t g);
 void reopen_reply(void);
 void open_reply(void);
+void task_reply(void);
 
 /* dmap.c */
 void lock_dmap(struct dmap *dp);
index 4ad64ab171671aa83788232690d4adda48984a56..61fcd6de48d2a9d18eaa0924be6e87e1f99dad44 100644 (file)
@@ -151,7 +151,7 @@ int read_write(struct fproc *rfp, int rw_flag, struct filp *f,
 
   if (size > SSIZE_MAX) return(EINVAL);
 
-  op = (rw_flag == READING ? VFS_DEV_READ : VFS_DEV_WRITE);
+  op = (rw_flag == READING ? DEV_READ_S : DEV_WRITE_S);
 
   if (S_ISFIFO(vp->v_mode)) {          /* Pipes */
        if (rfp->fp_cum_io_partial != 0) {
@@ -165,7 +165,7 @@ int read_write(struct fproc *rfp, int rw_flag, struct filp *f,
   } else if (S_ISCHR(vp->v_mode)) {    /* Character special files. */
        dev_t dev;
        int suspend_reopen;
-       int op = (rw_flag == READING ? VFS_DEV_READ : VFS_DEV_WRITE);
+       int op = (rw_flag == READING ? DEV_READ_S : DEV_WRITE_S);
 
        if(rw_flag == PEEKING) {
                printf("read_write: peek on char device makes no sense\n");
index 46a480de497f9736e10afe0bada18e76f387b3e1..81f20e0769dbcb867b1daedd5caa0b4c12b316ba 100644 (file)
@@ -52,11 +52,9 @@ static int is_regular_file(struct filp *f);
 static int is_pipe(struct filp *f);
 static int is_supported_major(struct filp *f);
 static void select_lock_filp(struct filp *f, int ops);
-static int select_request_async(struct filp *f, int *ops, int block);
 static int select_request_file(struct filp *f, int *ops, int block);
 static int select_request_major(struct filp *f, int *ops, int block);
 static int select_request_pipe(struct filp *f, int *ops, int block);
-static int select_request_sync(struct filp *f, int *ops, int block);
 static void select_cancel_all(struct selectentry *e);
 static void select_cancel_filp(struct filp *f);
 static void select_return(struct selectentry *);
@@ -336,13 +334,16 @@ static int is_supported_major(struct filp *f)
 }
 
 /*===========================================================================*
- *                             select_request_async                         *
+ *                             select_request_major                         *
  *===========================================================================*/
-static int select_request_async(struct filp *f, int *ops, int block)
+static int select_request_major(struct filp *f, int *ops, int block)
 {
   int r, rops, major;
   struct dmap *dp;
 
+  major = major(f->filp_vno->v_sdev);
+  if (major < 0 || major >= NR_DEVICES) return(ENXIO);
+
   rops = *ops;
 
   /* By default, nothing to do */
@@ -375,20 +376,15 @@ static int select_request_async(struct filp *f, int *ops, int block)
   if (f->filp_select_flags & FSF_BUSY)
        return(SUSPEND);
 
-  major = major(f->filp_vno->v_sdev);
-  if (major < 0 || major >= NR_DEVICES) return(ENXIO);
   dp = &dmap[major];
   if (dp->dmap_sel_filp)
        return(SUSPEND);
 
   f->filp_select_flags &= ~FSF_UPDATE;
-  r = dev_io(VFS_DEV_SELECT, f->filp_vno->v_sdev, rops, NULL, 0, 0, 0, FALSE);
-  if (r < 0 && r != SUSPEND)
+  r = dev_select(f->filp_vno->v_sdev, rops);
+  if (r != OK)
        return(r);
 
-  if (r != SUSPEND)
-       panic("select_request_asynch: expected SUSPEND got: %d", r);
-
   dp->dmap_sel_filp = f;
   f->filp_select_flags |= FSF_BUSY;
 
@@ -405,40 +401,6 @@ static int select_request_file(struct filp *UNUSED(f), int *UNUSED(ops),
   return(OK);
 }
 
-/*===========================================================================*
- *                             select_request_major                         *
- *===========================================================================*/
-static int select_request_major(struct filp *f, int *ops, int block)
-{
-  int major, r;
-
-  major = major(f->filp_vno->v_sdev);
-  if (major < 0 || major >= NR_DEVICES) return(ENXIO);
-
-  if (dev_style_asyn(dmap[major].dmap_style))
-       r = select_request_async(f, ops, block);
-  else
-       r = select_request_sync(f, ops, block);
-
-  return(r);
-}
-
-/*===========================================================================*
- *                             select_request_sync                          *
- *===========================================================================*/
-static int select_request_sync(struct filp *f, int *ops, int block)
-{
-  int rops;
-
-  rops = *ops;
-  if (block) rops |= SEL_NOTIFY;
-  *ops = dev_io(VFS_DEV_SELECT, f->filp_vno->v_sdev, rops, NULL, 0, 0, 0,FALSE);
-  if (*ops < 0)
-       return(*ops);
-
-  return(OK);
-}
-
 /*===========================================================================*
  *                             select_request_pipe                          *
  *===========================================================================*/