]> Zhao Yanbai Git Server - minix.git/commitdiff
VFS - no CANCEL for async non-blocking operations
authorTomas Hruby <tom@minix3.org>
Mon, 20 Feb 2012 13:19:29 +0000 (13:19 +0000)
committerTomas Hruby <tom@minix3.org>
Fri, 2 Mar 2012 15:44:48 +0000 (15:44 +0000)
- if an operation (R, W, IOCTL) is non blocking, a flag is set
  and sent to the device.

- nothing changes for sync devices

- asyn devices should reply asap if an operation is non-blocking.
  We must trust the devices, but we had to trust them anyway to
  reply to CANCEL correctly

- we safe sending CANCEL commands to asyn devices. This greatly
  simplifies the protocol. Asynchronous devices can always reply
  when a reply is ready and do not need to deal with other
  situations

- currently, none of our drivers use the flags since they drive
  virtual devices which do not block

drivers/hello/hello.c
drivers/log/log.c
drivers/memory/memory.c
drivers/random/main.c
include/minix/chardriver.h
include/minix/com.h
lib/libchardriver/chardriver.c
servers/vfs/device.c

index 21f60b537742a870d7c973dd014fc6da7c5ac619..c317563a4e17a8d5e2c919c9bc361506039c749b 100644 (file)
@@ -14,7 +14,8 @@ FORWARD _PROTOTYPE( struct device * hello_prepare, (dev_t device) );
 FORWARD _PROTOTYPE( int hello_transfer,  (endpoint_t endpt, int opcode,
                                           u64_t position, iovec_t *iov,
                                           unsigned int nr_req,
-                                          endpoint_t user_endpt) );
+                                          endpoint_t user_endpt,
+                                         unsigned int flags) );
 
 /* SEF functions and variables. */
 FORWARD _PROTOTYPE( void sef_local_startup, (void) );
@@ -63,7 +64,8 @@ PRIVATE struct device * hello_prepare(dev_t UNUSED(dev))
 }
 
 PRIVATE int hello_transfer(endpoint_t endpt, int opcode, u64_t position,
-    iovec_t *iov, unsigned nr_req, endpoint_t UNUSED(user_endpt))
+    iovec_t *iov, unsigned nr_req, endpoint_t UNUSED(user_endpt),
+    unsigned int UNUSED(flags))
 {
     int bytes, ret;
 
index 7d08dc4054974024e65c9104aa39e16ee1bf19bb..98aa7cdb1f21adec8a1c2cd2e331f0b92ba463cd 100644 (file)
@@ -25,7 +25,7 @@ PRIVATE int log_device = -1;                  /* current device */
 FORWARD _PROTOTYPE( struct device *log_prepare, (dev_t device) );
 FORWARD _PROTOTYPE( int log_transfer, (endpoint_t endpt, int opcode,
        u64_t position, iovec_t *iov, unsigned int nr_req,
-       endpoint_t user_endpt) );
+       endpoint_t user_endpt, unsigned int flags) );
 FORWARD _PROTOTYPE( int log_do_open, (message *m_ptr) );
 FORWARD _PROTOTYPE( int log_cancel, (message *m_ptr) );
 FORWARD _PROTOTYPE( int log_select, (message *m_ptr) );
@@ -281,7 +281,8 @@ PRIVATE int log_transfer(
   u64_t UNUSED(position),      /* offset on device to read or write */
   iovec_t *iov,                        /* pointer to read or write request vector */
   unsigned int nr_req,         /* length of request vector */
-  endpoint_t user_endpt                /* endpoint of user process */
+  endpoint_t user_endpt,       /* endpoint of user process */
+  unsigned int UNUSED(flags)
 )
 {
 /* Read or write one the driver's minor devices. */
index e1805a01b7969a7e742689d850c14d525c15980f..df297aebcc5c417a39702b18a512c562d7a8a56d 100644 (file)
@@ -47,7 +47,7 @@ PRIVATE int openct[NR_DEVS];
 FORWARD _PROTOTYPE( struct device *m_prepare, (dev_t device)           );
 FORWARD _PROTOTYPE( int m_transfer, (endpoint_t endpt, int opcode,
        u64_t position, iovec_t *iov, unsigned int nr_req,
-       endpoint_t user_endpt)                                          );
+       endpoint_t user_endpt, unsigned int flags)                      );
 FORWARD _PROTOTYPE( int m_do_open, (message *m_ptr)                    );
 FORWARD _PROTOTYPE( int m_do_close, (message *m_ptr)                   );
 
@@ -231,7 +231,8 @@ PRIVATE int m_transfer(
   u64_t pos64,                 /* offset on device to read or write */
   iovec_t *iov,                        /* pointer to read or write request vector */
   unsigned int nr_req,         /* length of request vector */
-  endpoint_t UNUSED(user_endpt)        /* endpoint of user process */
+  endpoint_t UNUSED(user_endpt),/* endpoint of user process */
+  unsigned int UNUSED(flags)
 )
 {
 /* Read or write one the driver's character devices. */
index 492d19ff9c7353066de8fd6e6789b10d0beae0d8..e6cf2ea3f54b10a9d2bb8d86adc3497a989c6793 100644 (file)
@@ -23,7 +23,7 @@ extern int errno;                     /* error number for PM calls */
 FORWARD _PROTOTYPE( struct device *r_prepare, (dev_t device) );
 FORWARD _PROTOTYPE( int r_transfer, (endpoint_t endpt, int opcode,
        u64_t position, iovec_t *iov, unsigned int nr_req,
-       endpoint_t user_endpt) );
+       endpoint_t user_endpt, unsigned int flags) );
 FORWARD _PROTOTYPE( int r_do_open, (message *m_ptr) );
 FORWARD _PROTOTYPE( void r_random, (message *m_ptr) );
 FORWARD _PROTOTYPE( void r_updatebin, (int source,
@@ -142,7 +142,8 @@ PRIVATE int r_transfer(
   u64_t position,              /* offset on device to read or write */
   iovec_t *iov,                        /* pointer to read or write request vector */
   unsigned int nr_req,         /* length of request vector */
-  endpoint_t UNUSED(user_endpt)        /* endpoint of user process */
+  endpoint_t UNUSED(user_endpt),/* endpoint of user process */
+  unsigned int UNUSED(flags)
 )
 {
 /* Read or write one the driver's minor devices. */
index fe3f64d79654e2d7a803b601e86d69da62cc42dc..79089a565ae038164c7ba662e68b6ac9e8c4aa46 100644 (file)
@@ -11,7 +11,7 @@ struct chardriver {
   _PROTOTYPE( struct device *(*cdr_prepare), (dev_t device) );
   _PROTOTYPE( int (*cdr_transfer), (endpoint_t endpt, int opcode,
        u64_t position, iovec_t *iov, unsigned int nr_req,
-       endpoint_t user_endpt) );
+       endpoint_t user_endpt, unsigned int flags) );
   _PROTOTYPE( void (*cdr_cleanup), (void) );
   _PROTOTYPE( void (*cdr_alarm), (message *m_ptr) );
   _PROTOTYPE( int (*cdr_cancel), (message *m_ptr) );
index c1c4f6f40c516709ac8d7008adebc2b8c22e0c30..c7f03fb6722ee986a855b81092afe5c7160bf2c0 100644 (file)
 #define HIGHPOS                m2_l2   /* file offset (high 4 bytes) */
 #define ADDRESS        m2_p1   /* core buffer address */
 #define IO_GRANT       m2_p1   /* grant id (for DEV_*_S variants) */
+#define FLAGS          m2_s1   /* operation flags */
+
+#define FLG_OP_NONBLOCK        0x1 /* operation is non blocking */
 
 /* Field names for DEV_SELECT messages to character device drivers. */
 #define DEV_MINOR      m2_i1   /* minor device */
index 2d0517a782d9aaadd90750721160922c25ccd577..c8cf63f1581309168d9732bee49a9c50635d9130 100644 (file)
@@ -241,8 +241,10 @@ PRIVATE int do_rdwt(struct chardriver *cdp, message *mp)
   if ((*cdp->cdr_prepare)(mp->DEVICE) == NULL) return(ENXIO);
 
   /* Create a one element scatter/gather vector for the buffer. */
-  if(mp->m_type == DEV_READ_S) opcode = DEV_GATHER_S;
-  else opcode =  DEV_SCATTER_S;
+  if(mp->m_type == DEV_READ_S)
+         opcode = DEV_GATHER_S;
+  else
+         opcode =  DEV_SCATTER_S;
 
   iovec1.iov_addr = (vir_bytes) mp->IO_GRANT;
   iovec1.iov_size = mp->COUNT;
@@ -250,7 +252,7 @@ PRIVATE int do_rdwt(struct chardriver *cdp, message *mp)
   /* Transfer bytes from/to the device. */
   position= make64(mp->POSITION, mp->HIGHPOS);
   r = (*cdp->cdr_transfer)(mp->m_source, opcode, position, &iovec1, 1,
-       mp->USER_ENDPT);
+       mp->USER_ENDPT, mp->FLAGS);
 
   /* Return the number of bytes transferred or an error code. */
   return(r == OK ? (int) (mp->COUNT - iovec1.iov_size) : r);
@@ -290,7 +292,7 @@ PRIVATE int do_vrdwt(struct chardriver *cdp, message *mp)
   opcode = mp->m_type;
   position= make64(mp->POSITION, mp->HIGHPOS);
   r = (*cdp->cdr_transfer)(mp->m_source, opcode, position, iovec, nr_req,
-       mp->USER_ENDPT);
+       mp->USER_ENDPT, mp->FLAGS);
 
   /* Copy the I/O vector back to the caller. */
   if (OK != sys_safecopyto(mp->m_source, (vir_bytes) mp->IO_GRANT,
index 8626550de17b25e3f65b700a95dd4aa559e0d249..4cb5fdb67d99d27bddbca712330d9b225ed454b4 100644 (file)
@@ -409,7 +409,7 @@ PUBLIC int dev_io(
   int safe, minor_dev, major_dev;
   void *buf_used;
   endpoint_t ioproc;
-  int ret;
+  int ret, is_asyn;
 
   pos_lo = ex64lo(pos);
   pos_high = ex64hi(pos);
@@ -447,6 +447,8 @@ PUBLIC int dev_io(
                            (endpoint_t *) &dev_mess.USER_ENDPT, &buf_used,
                            bytes, &pos_lo);
 
+  is_asyn = dev_style_asyn(dp->dmap_style);
+
   /* If the safe conversion was done, set the IO_GRANT to
    * the grant id.
    */
@@ -458,6 +460,10 @@ PUBLIC int dev_io(
   dev_mess.POSITION = pos_lo;
   dev_mess.COUNT    = bytes;
   dev_mess.HIGHPOS  = pos_high;
+  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;
@@ -476,7 +482,7 @@ PUBLIC int dev_io(
 
   /* Task has completed.  See if call completed. */
   if (ret == SUSPEND) {
-       if ((flags & O_NONBLOCK) && !dev_style_asyn(dp->dmap_style)) {
+       if ((flags & O_NONBLOCK) && !is_asyn) {
                /* Not supposed to block. */
                ret = cancel_nblock(dp, minor_dev, call_nr, ioproc, gid);
                if (ret == EINTR)
@@ -491,7 +497,7 @@ PUBLIC int dev_io(
                fp->fp_grant = gid;     /* revoke this when unsuspended. */
                fp->fp_ioproc = ioproc;
 
-               if (flags & O_NONBLOCK) {
+               if ((flags & O_NONBLOCK) && !is_asyn) {
                        /* Not supposed to block, send cancel message */
                        cancel_nblock(dp, minor_dev, call_nr, ioproc, gid);
                        /*