summaryrefslogtreecommitdiffstats
path: root/sys/geom/raid3
diff options
context:
space:
mode:
Diffstat (limited to 'sys/geom/raid3')
-rw-r--r--sys/geom/raid3/g_raid3.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/sys/geom/raid3/g_raid3.c b/sys/geom/raid3/g_raid3.c
index e60bf9b..65f4c0f 100644
--- a/sys/geom/raid3/g_raid3.c
+++ b/sys/geom/raid3/g_raid3.c
@@ -966,7 +966,7 @@ g_raid3_clone_bio(struct g_raid3_softc *sc, struct bio *pbp)
if (cbp->bio_data == NULL) {
if (size > 16384)
g_raid3_64k_failed++;
- if (size > 4096)
+ else if (size > 4096)
g_raid3_16k_failed++;
else
g_raid3_4k_failed++;
@@ -1560,6 +1560,17 @@ g_raid3_register_request(struct bio *pbp)
if (cbp == NULL) {
while ((cbp = G_RAID3_HEAD_BIO(pbp)) != NULL)
g_raid3_destroy_bio(sc, cbp);
+ /*
+ * To prevent deadlock, we must run back up
+ * with the ENOMEM for failed requests of any
+ * of our consumers. Our own sync requests
+ * can stick around, as they are finite.
+ */
+ if ((pbp->bio_cflags &
+ G_RAID3_BIO_CFLAG_REGULAR) != 0) {
+ g_io_deliver(pbp, ENOMEM);
+ return (0);
+ }
return (ENOMEM);
}
cbp->bio_offset = offset;
OpenPOWER on IntegriCloud