VFS - cancel_nblock()

- duplicate code in dev_io() which sends CANCEL in case of a
  non-blocking operation moved to cancel_nblock()
This commit is contained in:
Tomas Hruby 2012-02-07 15:33:32 +00:00
parent 98afd590c4
commit 35eb88461d

View File

@ -362,6 +362,32 @@ u32_t *pos_lo;
return(0); return(0);
} }
PRIVATE int cancel_nblock(struct dmap * dp,
int minor,
int call,
endpoint_t ioproc,
cp_grant_id_t gid)
{
message dev_mess;
dev_mess.m_type = CANCEL;
dev_mess.USER_ENDPT = ioproc;
dev_mess.IO_GRANT = (char *) gid;
/* This R_BIT/W_BIT check taken from suspend()/unpause()
* logic. Mode is expected in the COUNT field.
*/
dev_mess.COUNT = 0;
if (call == READ)
dev_mess.COUNT = R_BIT;
else if (call == WRITE)
dev_mess.COUNT = W_BIT;
dev_mess.DEVICE = minor;
(*dp->dmap_io)(dp->dmap_driver, &dev_mess);
return dev_mess.REP_STATUS;
}
/*===========================================================================* /*===========================================================================*
* dev_io * * dev_io *
*===========================================================================*/ *===========================================================================*/
@ -384,6 +410,7 @@ PUBLIC int dev_io(
int safe, minor_dev, major_dev; int safe, minor_dev, major_dev;
void *buf_used; void *buf_used;
endpoint_t ioproc; endpoint_t ioproc;
int ret;
pos_lo = ex64lo(pos); pos_lo = ex64lo(pos);
pos_high = ex64hi(pos); pos_high = ex64hi(pos);
@ -446,24 +473,16 @@ PUBLIC int dev_io(
return(EIO); return(EIO);
} }
ret = dev_mess.REP_STATUS;
/* Task has completed. See if call completed. */ /* Task has completed. See if call completed. */
if (dev_mess.REP_STATUS == SUSPEND) { if (ret == SUSPEND) {
if ((flags & O_NONBLOCK) && !(dp->dmap_style == STYLE_DEVA || if ((flags & O_NONBLOCK) && !(dp->dmap_style == STYLE_DEVA ||
dp->dmap_style == STYLE_CLONE_A)) { dp->dmap_style == STYLE_CLONE_A)) {
/* Not supposed to block. */ /* Not supposed to block. */
dev_mess.m_type = CANCEL; ret = cancel_nblock(dp, minor_dev, call_nr, ioproc, gid);
dev_mess.USER_ENDPT = ioproc; if (ret == EINTR)
dev_mess.IO_GRANT = (char *) gid; ret = EAGAIN;
/* This R_BIT/W_BIT check taken from suspend()/unpause()
* logic. Mode is expected in the COUNT field.
*/
dev_mess.COUNT = 0;
if (call_nr == READ) dev_mess.COUNT = R_BIT;
else if (call_nr == WRITE) dev_mess.COUNT = W_BIT;
dev_mess.DEVICE = minor_dev;
(*dp->dmap_io)(dp->dmap_driver, &dev_mess);
if (dev_mess.REP_STATUS == EINTR) dev_mess.REP_STATUS = EAGAIN;
} else { } else {
/* select() will do suspending itself. */ /* select() will do suspending itself. */
if(op != DEV_SELECT) { if(op != DEV_SELECT) {
@ -476,20 +495,11 @@ PUBLIC int dev_io(
if (flags & O_NONBLOCK) { if (flags & O_NONBLOCK) {
/* Not supposed to block, send cancel message */ /* Not supposed to block, send cancel message */
dev_mess.m_type = CANCEL; cancel_nblock(dp, minor_dev, call_nr, ioproc, gid);
dev_mess.USER_ENDPT = ioproc; /*
dev_mess.IO_GRANT = (char *) gid; * FIXME Should do something about EINTR -> EAGAIN
* mapping
/* This R_BIT/W_BIT check taken from suspend()/unpause()
* logic. Mode is expected in the COUNT field.
*/ */
dev_mess.COUNT = 0;
if(call_nr == READ) dev_mess.COUNT = R_BIT;
else if(call_nr == WRITE) dev_mess.COUNT = W_BIT;
dev_mess.DEVICE = minor_dev;
(*dp->dmap_io)(dp->dmap_driver, &dev_mess);
/* Should do something about EINTR -> EAGAIN mapping */
} }
return(SUSPEND); return(SUSPEND);
} }
@ -498,7 +508,7 @@ PUBLIC int dev_io(
/* No suspend, or cancelled suspend, so I/O is over and can be cleaned up. */ /* No suspend, or cancelled suspend, so I/O is over and can be cleaned up. */
if(safe) cpf_revoke(gid); if(safe) cpf_revoke(gid);
return(dev_mess.REP_STATUS); return ret;
} }
/*===========================================================================* /*===========================================================================*