Polish the work/state engine in preparation for HW-crypto support.

This commit is contained in:
Poul-Henning Kamp 2004-02-08 10:19:18 +00:00
parent d091e630f1
commit df3df337b8

View File

@ -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));
} }