Add CANCEL command which allows to remove one request from the queue or

all requests from the queue if request number is not given.

Bump version number.

Approved by:	re (scottl)
This commit is contained in:
Pawel Jakub Dawidek 2005-07-08 21:08:53 +00:00
parent bd6875fb78
commit 84436f14c4
2 changed files with 53 additions and 4 deletions

View File

@ -442,8 +442,11 @@ g_gate_create(struct g_gate_ctl_create *ggio)
} }
#define G_GATE_CHECK_VERSION(ggio) do { \ #define G_GATE_CHECK_VERSION(ggio) do { \
if ((ggio)->gctl_version != G_GATE_VERSION) \ if ((ggio)->gctl_version != G_GATE_VERSION) { \
printf("Version mismatch %d != %d.\n", \
ggio->gctl_version, G_GATE_VERSION); \
return (EINVAL); \ return (EINVAL); \
} \
} while (0) } while (0)
static int static int
g_gate_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td) g_gate_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td)
@ -488,6 +491,44 @@ g_gate_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct threa
g_gate_release(sc); g_gate_release(sc);
return (error); return (error);
} }
case G_GATE_CMD_CANCEL:
{
struct g_gate_ctl_cancel *ggio = (void *)addr;
struct bio *tbp, *lbp;
G_GATE_CHECK_VERSION(ggio);
sc = g_gate_hold(ggio->gctl_unit);
if (sc == NULL)
return (ENXIO);
lbp = NULL;
mtx_lock(&sc->sc_queue_mtx);
TAILQ_FOREACH_SAFE(bp, &sc->sc_outqueue.queue, bio_queue, tbp) {
if (ggio->gctl_seq == 0 ||
ggio->gctl_seq == (uintptr_t)bp->bio_driver1) {
G_GATE_LOGREQ(1, bp, "Request canceled.");
bioq_remove(&sc->sc_outqueue, bp);
/*
* Be sure to put requests back onto incoming
* queue in the proper order.
*/
if (lbp == NULL)
bioq_insert_head(&sc->sc_inqueue, bp);
else {
TAILQ_INSERT_AFTER(&sc->sc_inqueue.queue,
lbp, bp, bio_queue);
}
lbp = bp;
/*
* If only one request was canceled, leave now.
*/
if (ggio->gctl_seq != 0)
break;
}
}
mtx_unlock(&sc->sc_queue_mtx);
g_gate_release(sc);
return (error);
}
case G_GATE_CMD_START: case G_GATE_CMD_START:
{ {
struct g_gate_ctl_io *ggio = (void *)addr; struct g_gate_ctl_io *ggio = (void *)addr;
@ -526,6 +567,7 @@ g_gate_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct threa
ggio->gctl_seq = (uintptr_t)bp->bio_driver1; ggio->gctl_seq = (uintptr_t)bp->bio_driver1;
ggio->gctl_offset = bp->bio_offset; ggio->gctl_offset = bp->bio_offset;
ggio->gctl_length = bp->bio_length; ggio->gctl_length = bp->bio_length;
switch (bp->bio_cmd) { switch (bp->bio_cmd) {
case BIO_READ: case BIO_READ:
break; break;

View File

@ -41,7 +41,7 @@
#define G_GATE_MOD_NAME "ggate" #define G_GATE_MOD_NAME "ggate"
#define G_GATE_CTL_NAME "ggctl" #define G_GATE_CTL_NAME "ggctl"
#define G_GATE_VERSION 0 #define G_GATE_VERSION 1
/* /*
* Maximum number of request that can be stored in * Maximum number of request that can be stored in
@ -56,8 +56,9 @@
#define G_GATE_CMD_CREATE _IOWR('m', 0, struct g_gate_ctl_create) #define G_GATE_CMD_CREATE _IOWR('m', 0, struct g_gate_ctl_create)
#define G_GATE_CMD_DESTROY _IOWR('m', 1, struct g_gate_ctl_destroy) #define G_GATE_CMD_DESTROY _IOWR('m', 1, struct g_gate_ctl_destroy)
#define G_GATE_CMD_START _IOWR('m', 2, struct g_gate_ctl_io) #define G_GATE_CMD_CANCEL _IOWR('m', 2, struct g_gate_ctl_cancel)
#define G_GATE_CMD_DONE _IOWR('m', 3, struct g_gate_ctl_io) #define G_GATE_CMD_START _IOWR('m', 3, struct g_gate_ctl_io)
#define G_GATE_CMD_DONE _IOWR('m', 4, struct g_gate_ctl_io)
#define G_GATE_INFOSIZE 2048 #define G_GATE_INFOSIZE 2048
@ -129,6 +130,12 @@ struct g_gate_ctl_destroy {
int gctl_force; int gctl_force;
}; };
struct g_gate_ctl_cancel {
u_int gctl_version;
int gctl_unit;
uintptr_t gctl_seq;
};
struct g_gate_ctl_io { struct g_gate_ctl_io {
u_int gctl_version; u_int gctl_version;
int gctl_unit; int gctl_unit;