Polish the work/state engine in preparation for HW-crypto support.
This commit is contained in:
parent
d091e630f1
commit
df3df337b8
@ -384,6 +384,22 @@ g_bde_contribute(struct bio *bp, off_t bytes, int error)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is the common case "we're done with this work package" function
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void
|
||||||
|
g_bde_work_done(struct g_bde_work *wp, int error)
|
||||||
|
{
|
||||||
|
|
||||||
|
g_bde_contribute(wp->bp, wp->length, error);
|
||||||
|
if (wp->sp != NULL)
|
||||||
|
g_bde_delete_sector(wp->softc, wp->sp);
|
||||||
|
if (wp->ksp != NULL)
|
||||||
|
g_bde_release_keysector(wp);
|
||||||
|
g_bde_delete_work(wp);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A write operation has finished. When we have all expected cows in the
|
* A write operation has finished. When we have all expected cows in the
|
||||||
* barn close the door and call it a day.
|
* barn close the door and call it a day.
|
||||||
@ -413,9 +429,7 @@ g_bde_write_done(struct bio *bp)
|
|||||||
|
|
||||||
if (wp->bp->bio_cmd == BIO_DELETE) {
|
if (wp->bp->bio_cmd == BIO_DELETE) {
|
||||||
KASSERT(sp == wp->sp, ("trashed delete op"));
|
KASSERT(sp == wp->sp, ("trashed delete op"));
|
||||||
g_bde_contribute(wp->bp, wp->length, wp->error);
|
g_bde_work_done(wp, wp->error);
|
||||||
g_bde_delete_sector(sc, sp);
|
|
||||||
g_bde_delete_work(wp);
|
|
||||||
mtx_unlock(&sc->worklist_mutex);
|
mtx_unlock(&sc->worklist_mutex);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -428,11 +442,8 @@ g_bde_write_done(struct bio *bp)
|
|||||||
} else {
|
} else {
|
||||||
sp->state = VALID;
|
sp->state = VALID;
|
||||||
}
|
}
|
||||||
if (wp->sp == NULL && wp->ksp != NULL && wp->ksp->state == VALID) {
|
if (wp->sp == NULL && wp->ksp != NULL && wp->ksp->state == VALID)
|
||||||
g_bde_contribute(wp->bp, wp->length, wp->error);
|
g_bde_work_done(wp, wp->error);
|
||||||
g_bde_release_keysector(wp);
|
|
||||||
g_bde_delete_work(wp);
|
|
||||||
}
|
|
||||||
mtx_unlock(&sc->worklist_mutex);
|
mtx_unlock(&sc->worklist_mutex);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -536,22 +547,22 @@ void
|
|||||||
g_bde_worker(void *arg)
|
g_bde_worker(void *arg)
|
||||||
{
|
{
|
||||||
struct g_bde_softc *sc;
|
struct g_bde_softc *sc;
|
||||||
struct g_bde_work *wp;
|
struct g_bde_work *wp, *twp;
|
||||||
struct g_geom *gp;
|
struct g_geom *gp;
|
||||||
int busy, error;
|
int restart, error;
|
||||||
|
|
||||||
gp = arg;
|
gp = arg;
|
||||||
sc = gp->softc;
|
sc = gp->softc;
|
||||||
|
|
||||||
mtx_lock(&sc->worklist_mutex);
|
mtx_lock(&sc->worklist_mutex);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
busy = 0;
|
restart = 0;
|
||||||
g_trace(G_T_TOPOLOGY, "g_bde_worker scan");
|
g_trace(G_T_TOPOLOGY, "g_bde_worker scan");
|
||||||
TAILQ_FOREACH(wp, &sc->worklist, list) {
|
TAILQ_FOREACH_SAFE(wp, &sc->worklist, list, twp) {
|
||||||
KASSERT(wp != NULL, ("NULL wp"));
|
KASSERT(wp != NULL, ("NULL wp"));
|
||||||
KASSERT(wp->softc != NULL, ("NULL wp->softc"));
|
KASSERT(wp->softc != NULL, ("NULL wp->softc"));
|
||||||
if (wp->state != WAIT)
|
if (wp->state != WAIT)
|
||||||
continue; /* Not interesting here */
|
continue; /* Not interesting here */
|
||||||
|
|
||||||
KASSERT(wp->bp != NULL, ("NULL wp->bp"));
|
KASSERT(wp->bp != NULL, ("NULL wp->bp"));
|
||||||
KASSERT(wp->sp != NULL, ("NULL wp->sp"));
|
KASSERT(wp->sp != NULL, ("NULL wp->sp"));
|
||||||
@ -562,60 +573,52 @@ g_bde_worker(void *arg)
|
|||||||
if (wp->ksp->state == IO)
|
if (wp->ksp->state == IO)
|
||||||
continue;
|
continue;
|
||||||
KASSERT(wp->ksp->state == VALID,
|
KASSERT(wp->ksp->state == VALID,
|
||||||
("Illegal sector state (JUNK ?)"));
|
("Illegal sector state (%d)",
|
||||||
|
wp->ksp->state));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wp->bp->bio_cmd == BIO_READ &&
|
if (wp->bp->bio_cmd == BIO_READ && wp->sp->state == IO)
|
||||||
wp->sp->state == IO)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (wp->ksp != NULL && wp->ksp->error != 0) {
|
if (wp->ksp != NULL && wp->ksp->error != 0) {
|
||||||
g_bde_contribute(wp->bp, wp->length,
|
g_bde_work_done(wp, wp->ksp->error);
|
||||||
wp->ksp->error);
|
continue;
|
||||||
g_bde_delete_sector(sc, wp->sp);
|
|
||||||
g_bde_release_keysector(wp);
|
|
||||||
g_bde_delete_work(wp);
|
|
||||||
busy++;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
switch(wp->bp->bio_cmd) {
|
switch(wp->bp->bio_cmd) {
|
||||||
case BIO_READ:
|
case BIO_READ:
|
||||||
if (wp->ksp == NULL) {
|
if (wp->ksp == NULL) {
|
||||||
KASSERT(wp->error != 0,
|
KASSERT(wp->error != 0,
|
||||||
("BIO_READ, no ksp and no error"));
|
("BIO_READ, no ksp and no error"));
|
||||||
g_bde_contribute(wp->bp, wp->length,
|
g_bde_work_done(wp, wp->error);
|
||||||
wp->error);
|
break;
|
||||||
} else {
|
|
||||||
if (wp->sp->error == 0) {
|
|
||||||
mtx_unlock(&sc->worklist_mutex);
|
|
||||||
g_bde_crypt_read(wp);
|
|
||||||
mtx_lock(&sc->worklist_mutex);
|
|
||||||
}
|
|
||||||
g_bde_contribute(wp->bp, wp->length,
|
|
||||||
wp->sp->error);
|
|
||||||
}
|
}
|
||||||
g_bde_delete_sector(sc, wp->sp);
|
if (wp->sp->error != 0) {
|
||||||
if (wp->ksp != NULL)
|
g_bde_work_done(wp, wp->sp->error);
|
||||||
g_bde_release_keysector(wp);
|
break;
|
||||||
g_bde_delete_work(wp);
|
}
|
||||||
|
mtx_unlock(&sc->worklist_mutex);
|
||||||
|
g_bde_crypt_read(wp);
|
||||||
|
mtx_lock(&sc->worklist_mutex);
|
||||||
|
restart++;
|
||||||
|
g_bde_work_done(wp, wp->sp->error);
|
||||||
break;
|
break;
|
||||||
case BIO_WRITE:
|
case BIO_WRITE:
|
||||||
wp->state = FINISH;
|
wp->state = FINISH;
|
||||||
KASSERT(wp->sp->owner == wp, ("Write not owner sp"));
|
KASSERT(wp->sp->owner == wp,
|
||||||
KASSERT(wp->ksp->owner == wp, ("Write not owner ksp"));
|
("Write not owner sp"));
|
||||||
|
KASSERT(wp->ksp->owner == wp,
|
||||||
|
("Write not owner ksp"));
|
||||||
mtx_unlock(&sc->worklist_mutex);
|
mtx_unlock(&sc->worklist_mutex);
|
||||||
g_bde_crypt_write(wp);
|
g_bde_crypt_write(wp);
|
||||||
mtx_lock(&sc->worklist_mutex);
|
mtx_lock(&sc->worklist_mutex);
|
||||||
|
restart++;
|
||||||
error = g_bde_start_write(wp->sp);
|
error = g_bde_start_write(wp->sp);
|
||||||
if (error) {
|
if (error) {
|
||||||
g_bde_contribute(wp->bp, wp->length, error);
|
g_bde_work_done(wp, error);
|
||||||
g_bde_release_keysector(wp);
|
|
||||||
g_bde_delete_sector(sc, wp->sp);
|
|
||||||
g_bde_delete_work(wp);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
error = g_bde_start_write(wp->ksp);
|
error = g_bde_start_write(wp->ksp);
|
||||||
if (wp->error == 0)
|
if (wp->error != 0)
|
||||||
wp->error = error;
|
wp->error = error;
|
||||||
break;
|
break;
|
||||||
case BIO_DELETE:
|
case BIO_DELETE:
|
||||||
@ -623,13 +626,14 @@ g_bde_worker(void *arg)
|
|||||||
mtx_unlock(&sc->worklist_mutex);
|
mtx_unlock(&sc->worklist_mutex);
|
||||||
g_bde_crypt_delete(wp);
|
g_bde_crypt_delete(wp);
|
||||||
mtx_lock(&sc->worklist_mutex);
|
mtx_lock(&sc->worklist_mutex);
|
||||||
|
restart++;
|
||||||
g_bde_start_write(wp->sp);
|
g_bde_start_write(wp->sp);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
busy++;
|
if (restart)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!busy) {
|
if (!restart) {
|
||||||
/*
|
/*
|
||||||
* We don't look for our death-warrant until we are
|
* We don't look for our death-warrant until we are
|
||||||
* idle. Shouldn't make a difference in practice.
|
* idle. Shouldn't make a difference in practice.
|
||||||
@ -638,7 +642,7 @@ g_bde_worker(void *arg)
|
|||||||
break;
|
break;
|
||||||
g_trace(G_T_TOPOLOGY, "g_bde_worker sleep");
|
g_trace(G_T_TOPOLOGY, "g_bde_worker sleep");
|
||||||
error = msleep(sc, &sc->worklist_mutex,
|
error = msleep(sc, &sc->worklist_mutex,
|
||||||
PRIBIO, "g_bde", hz);
|
PRIBIO, "-", hz);
|
||||||
if (error == EWOULDBLOCK) {
|
if (error == EWOULDBLOCK) {
|
||||||
/*
|
/*
|
||||||
* Loose our skey cache in an orderly fashion.
|
* Loose our skey cache in an orderly fashion.
|
||||||
@ -678,46 +682,43 @@ g_bde_start2(struct g_bde_work *wp)
|
|||||||
KASSERT(wp->softc != NULL, ("NULL wp->softc"));
|
KASSERT(wp->softc != NULL, ("NULL wp->softc"));
|
||||||
g_trace(G_T_TOPOLOGY, "g_bde_start2(%p)", wp);
|
g_trace(G_T_TOPOLOGY, "g_bde_start2(%p)", wp);
|
||||||
sc = wp->softc;
|
sc = wp->softc;
|
||||||
if (wp->bp->bio_cmd == BIO_READ) {
|
switch (wp->bp->bio_cmd) {
|
||||||
|
case BIO_READ:
|
||||||
wp->sp = g_bde_new_sector(wp, 0);
|
wp->sp = g_bde_new_sector(wp, 0);
|
||||||
if (wp->sp == NULL) {
|
if (wp->sp == NULL) {
|
||||||
g_bde_contribute(wp->bp, wp->length, ENOMEM);
|
g_bde_work_done(wp, ENOMEM);
|
||||||
g_bde_delete_work(wp);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
wp->sp->size = wp->length;
|
wp->sp->size = wp->length;
|
||||||
wp->sp->data = wp->data;
|
wp->sp->data = wp->data;
|
||||||
if (g_bde_start_read(wp->sp) != 0) {
|
if (g_bde_start_read(wp->sp) != 0) {
|
||||||
g_bde_contribute(wp->bp, wp->length, ENOMEM);
|
g_bde_work_done(wp, ENOMEM);
|
||||||
g_bde_delete_sector(sc, wp->sp);
|
|
||||||
g_bde_delete_work(wp);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
g_bde_read_keysector(sc, wp);
|
g_bde_read_keysector(sc, wp);
|
||||||
if (wp->ksp == NULL)
|
if (wp->ksp == NULL)
|
||||||
wp->error = ENOMEM;
|
wp->error = ENOMEM;
|
||||||
} else if (wp->bp->bio_cmd == BIO_DELETE) {
|
break;
|
||||||
|
case BIO_DELETE:
|
||||||
wp->sp = g_bde_new_sector(wp, wp->length);
|
wp->sp = g_bde_new_sector(wp, wp->length);
|
||||||
if (wp->sp == NULL) {
|
if (wp->sp == NULL) {
|
||||||
g_bde_contribute(wp->bp, wp->length, ENOMEM);
|
g_bde_work_done(wp, ENOMEM);
|
||||||
g_bde_delete_work(wp);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else if (wp->bp->bio_cmd == BIO_WRITE) {
|
break;
|
||||||
|
case BIO_WRITE:
|
||||||
wp->sp = g_bde_new_sector(wp, wp->length);
|
wp->sp = g_bde_new_sector(wp, wp->length);
|
||||||
if (wp->sp == NULL) {
|
if (wp->sp == NULL) {
|
||||||
g_bde_contribute(wp->bp, wp->length, ENOMEM);
|
g_bde_work_done(wp, ENOMEM);
|
||||||
g_bde_delete_work(wp);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
g_bde_read_keysector(sc, wp);
|
g_bde_read_keysector(sc, wp);
|
||||||
if (wp->ksp == NULL) {
|
if (wp->ksp == NULL) {
|
||||||
g_bde_contribute(wp->bp, wp->length, ENOMEM);
|
g_bde_work_done(wp, ENOMEM);
|
||||||
g_bde_delete_sector(sc, wp->sp);
|
|
||||||
g_bde_delete_work(wp);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
break;
|
||||||
|
default:
|
||||||
KASSERT(0 == 1,
|
KASSERT(0 == 1,
|
||||||
("Wrong bio_cmd %d in g_bde_start2", wp->bp->bio_cmd));
|
("Wrong bio_cmd %d in g_bde_start2", wp->bp->bio_cmd));
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user