summaryrefslogtreecommitdiffstats
path: root/sys/geom/bde/g_bde_work.c
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>2003-04-25 21:20:57 +0000
committerphk <phk@FreeBSD.org>2003-04-25 21:20:57 +0000
commit017246b9b8dd3b24cd66f34840cceef6336634fa (patch)
treeb4c1b3cd5e4ab706ca890ba10d06b784be813d05 /sys/geom/bde/g_bde_work.c
parenta8b06a6a441f76581f3147c70a105b334a9fbdea (diff)
downloadFreeBSD-src-017246b9b8dd3b24cd66f34840cceef6336634fa.zip
FreeBSD-src-017246b9b8dd3b24cd66f34840cceef6336634fa.tar.gz
Fix a problem and slightly improve the ENOMEM handling:
Give up the entire bio as soon as we detect a problem. When we detect a problem, give up the bio by contributing the remainder with ENOMEM, rather than kicking the bio back right away. If we failed on a non-first iteration we previously could end up modifying fields in the bio after we delivered it. This could account for memory corruption (none directly reported) on machines with GBDE.
Diffstat (limited to 'sys/geom/bde/g_bde_work.c')
-rw-r--r--sys/geom/bde/g_bde_work.c23
1 files changed, 12 insertions, 11 deletions
diff --git a/sys/geom/bde/g_bde_work.c b/sys/geom/bde/g_bde_work.c
index d8186ce..9375051 100644
--- a/sys/geom/bde/g_bde_work.c
+++ b/sys/geom/bde/g_bde_work.c
@@ -720,18 +720,19 @@ g_bde_start1(struct bio *bp)
mtx_lock(&sc->worklist_mutex);
for(done = 0; done < bp->bio_length; ) {
wp = g_bde_new_work(sc);
- if (wp == NULL) {
- g_io_deliver(bp, ENOMEM);
- mtx_unlock(&sc->worklist_mutex);
- return;
+ if (wp != NULL) {
+ wp->bp = bp;
+ wp->offset = bp->bio_offset + done;
+ wp->data = bp->bio_data + done;
+ wp->length = bp->bio_length - done;
+ g_bde_map_sector(wp);
+ done += wp->length;
+ g_bde_start2(wp);
+ }
+ if (wp == NULL || bp->bio_error != 0) {
+ g_bde_contribute(bp, bp->bio_length - done, ENOMEM);
+ break;
}
- wp->bp = bp;
- wp->offset = bp->bio_offset + done;
- wp->data = bp->bio_data + done;
- wp->length = bp->bio_length - done;
- g_bde_map_sector(wp);
- done += wp->length;
- g_bde_start2(wp);
}
mtx_unlock(&sc->worklist_mutex);
return;
OpenPOWER on IntegriCloud