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:
parent
bd6875fb78
commit
84436f14c4
@ -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;
|
||||||
|
@ -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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user