summaryrefslogtreecommitdiffstats
path: root/sys/geom
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2015-03-12 10:20:53 +0000
committermav <mav@FreeBSD.org>2015-03-12 10:20:53 +0000
commit19bf0d882b83adc63cf9aeada8ca86c9a2bf8adb (patch)
treeb349253a49159be48870736e4230c6177a8cf88b /sys/geom
parentcc29b99b5c7678b30f105f23bd5e92ea81115b9e (diff)
downloadFreeBSD-src-19bf0d882b83adc63cf9aeada8ca86c9a2bf8adb.zip
FreeBSD-src-19bf0d882b83adc63cf9aeada8ca86c9a2bf8adb.tar.gz
Fix couple BIO_DELETE bugs in geom_mirror.
Do not report GEOM::candelete if none of providers support BIO_DELETE. If consumer still requests BIO_DELETE, report error instead of hanging. MFC after: 2 weeks
Diffstat (limited to 'sys/geom')
-rw-r--r--sys/geom/mirror/g_mirror.c26
1 files changed, 24 insertions, 2 deletions
diff --git a/sys/geom/mirror/g_mirror.c b/sys/geom/mirror/g_mirror.c
index 2fae439..89fb9c0 100644
--- a/sys/geom/mirror/g_mirror.c
+++ b/sys/geom/mirror/g_mirror.c
@@ -1021,6 +1021,23 @@ g_mirror_sync_done(struct bio *bp)
}
static void
+g_mirror_candelete(struct bio *bp)
+{
+ struct g_mirror_softc *sc;
+ struct g_mirror_disk *disk;
+ int *val;
+
+ sc = bp->bio_to->geom->softc;
+ LIST_FOREACH(disk, &sc->sc_disks, d_next) {
+ if (disk->d_flags & G_MIRROR_DISK_FLAG_CANDELETE)
+ break;
+ }
+ val = (int *)bp->bio_data;
+ *val = (disk != NULL);
+ g_io_deliver(bp, 0);
+}
+
+static void
g_mirror_kernel_dump(struct bio *bp)
{
struct g_mirror_softc *sc;
@@ -1114,9 +1131,10 @@ g_mirror_start(struct bio *bp)
g_mirror_flush(sc, bp);
return;
case BIO_GETATTR:
- if (g_handleattr_int(bp, "GEOM::candelete", 1))
+ if (!strcmp(bp->bio_attribute, "GEOM::candelete")) {
+ g_mirror_candelete(bp);
return;
- else if (strcmp("GEOM::kerneldump", bp->bio_attribute) == 0) {
+ } else if (strcmp("GEOM::kerneldump", bp->bio_attribute) == 0) {
g_mirror_kernel_dump(bp);
return;
}
@@ -1680,6 +1698,10 @@ g_mirror_register_request(struct bio *bp)
("Consumer %s not opened (r%dw%de%d).",
cp->provider->name, cp->acr, cp->acw, cp->ace));
}
+ if (bioq_first(&queue) == NULL) {
+ g_io_deliver(bp, EOPNOTSUPP);
+ return;
+ }
while ((cbp = bioq_takefirst(&queue)) != NULL) {
G_MIRROR_LOGREQ(3, cbp, "Sending request.");
cp = cbp->bio_caller1;
OpenPOWER on IntegriCloud