svn commit: r218600 - projects/graid/head/sys/geom/raid
Alexander Motin
mav at FreeBSD.org
Sat Feb 12 11:00:35 UTC 2011
Author: mav
Date: Sat Feb 12 11:00:34 2011
New Revision: 218600
URL: http://svn.freebsd.org/changeset/base/218600
Log:
Add BIO_FLUSH support.
Modified:
projects/graid/head/sys/geom/raid/g_raid.c
projects/graid/head/sys/geom/raid/g_raid.h
projects/graid/head/sys/geom/raid/tr_raid0.c
projects/graid/head/sys/geom/raid/tr_raid1.c
Modified: projects/graid/head/sys/geom/raid/g_raid.c
==============================================================================
--- projects/graid/head/sys/geom/raid/g_raid.c Sat Feb 12 09:12:11 2011 (r218599)
+++ projects/graid/head/sys/geom/raid/g_raid.c Sat Feb 12 11:00:34 2011 (r218600)
@@ -737,6 +737,54 @@ g_raid_dirty(struct g_raid_volume *vol)
g_raid_write_metadata(sc, vol, NULL, NULL);
}
+void
+g_raid_tr_flush_common(struct g_raid_tr_object *tr, struct bio *bp)
+{
+ struct g_raid_softc *sc;
+ struct g_raid_volume *vol;
+ struct g_raid_subdisk *sd;
+ struct bio_queue_head queue;
+ struct bio *cbp;
+ int i;
+
+ vol = tr->tro_volume;
+ sc = vol->v_softc;
+
+ /*
+ * Allocate all bios before sending any request, so we can return
+ * ENOMEM in nice and clean way.
+ */
+ bioq_init(&queue);
+ for (i = 0; i < vol->v_disks_count; i++) {
+ sd = &vol->v_subdisks[i];
+ if (sd->sd_state == G_RAID_SUBDISK_S_NONE ||
+ sd->sd_state == G_RAID_SUBDISK_S_FAILED)
+ continue;
+ cbp = g_clone_bio(bp);
+ if (cbp == NULL)
+ goto failure;
+ cbp->bio_caller1 = sd;
+ bioq_insert_tail(&queue, cbp);
+ }
+ for (cbp = bioq_first(&queue); cbp != NULL;
+ cbp = bioq_first(&queue)) {
+ bioq_remove(&queue, cbp);
+ sd = cbp->bio_caller1;
+ cbp->bio_caller1 = NULL;
+ g_raid_subdisk_iostart(sd, cbp);
+ }
+ return;
+failure:
+ for (cbp = bioq_first(&queue); cbp != NULL;
+ cbp = bioq_first(&queue)) {
+ bioq_remove(&queue, cbp);
+ g_destroy_bio(cbp);
+ }
+ if (bp->bio_error == 0)
+ bp->bio_error = ENOMEM;
+ g_raid_iodone(bp, bp->bio_error);
+}
+
static void
g_raid_tr_kerneldump_common_done(struct bio *bp)
{
@@ -832,10 +880,8 @@ g_raid_start(struct bio *bp)
case BIO_READ:
case BIO_WRITE:
case BIO_DELETE:
- break;
case BIO_FLUSH:
- g_io_deliver(bp, EOPNOTSUPP);
- return;
+ break;
case BIO_GETATTR:
if (!strcmp(bp->bio_attribute, "GEOM::kerneldump"))
g_raid_kerneldump(sc, bp);
Modified: projects/graid/head/sys/geom/raid/g_raid.h
==============================================================================
--- projects/graid/head/sys/geom/raid/g_raid.h Sat Feb 12 09:12:11 2011 (r218599)
+++ projects/graid/head/sys/geom/raid/g_raid.h Sat Feb 12 11:00:34 2011 (r218600)
@@ -373,6 +373,7 @@ void g_raid_write_metadata(struct g_raid
void g_raid_fail_disk(struct g_raid_softc *sc,
struct g_raid_subdisk *sd, struct g_raid_disk *disk);
+void g_raid_tr_flush_common(struct g_raid_tr_object *tr, struct bio *bp);
int g_raid_tr_kerneldump_common(struct g_raid_tr_object *tr,
void *virtual, vm_offset_t physical, off_t offset, size_t length);
Modified: projects/graid/head/sys/geom/raid/tr_raid0.c
==============================================================================
--- projects/graid/head/sys/geom/raid/tr_raid0.c Sat Feb 12 09:12:11 2011 (r218599)
+++ projects/graid/head/sys/geom/raid/tr_raid0.c Sat Feb 12 11:00:34 2011 (r218600)
@@ -200,6 +200,10 @@ g_raid_tr_iostart_raid0(struct g_raid_tr
g_raid_iodone(bp, EIO);
return;
}
+ if (bp->bio_cmd == BIO_FLUSH) {
+ g_raid_tr_flush_common(tr, bp);
+ return;
+ }
sc = vol->v_softc;
addr = bp->bio_data;
Modified: projects/graid/head/sys/geom/raid/tr_raid1.c
==============================================================================
--- projects/graid/head/sys/geom/raid/tr_raid1.c Sat Feb 12 09:12:11 2011 (r218599)
+++ projects/graid/head/sys/geom/raid/tr_raid1.c Sat Feb 12 11:00:34 2011 (r218600)
@@ -601,17 +601,8 @@ g_raid_tr_iostart_raid1_write(struct g_r
continue;
}
cbp = g_clone_bio(bp);
- if (cbp == NULL) {
- for (cbp = bioq_first(&queue); cbp != NULL;
- cbp = bioq_first(&queue)) {
- bioq_remove(&queue, cbp);
- g_destroy_bio(cbp);
- }
- if (bp->bio_error == 0)
- bp->bio_error = ENOMEM;
- g_raid_iodone(bp, bp->bio_error);
- return;
- }
+ if (cbp == NULL)
+ goto failure;
cbp->bio_caller1 = sd;
bioq_insert_tail(&queue, cbp);
}
@@ -622,7 +613,16 @@ g_raid_tr_iostart_raid1_write(struct g_r
cbp->bio_caller1 = NULL;
g_raid_subdisk_iostart(sd, cbp);
}
-
+ return;
+failure:
+ for (cbp = bioq_first(&queue); cbp != NULL;
+ cbp = bioq_first(&queue)) {
+ bioq_remove(&queue, cbp);
+ g_destroy_bio(cbp);
+ }
+ if (bp->bio_error == 0)
+ bp->bio_error = ENOMEM;
+ g_raid_iodone(bp, bp->bio_error);
}
static void
@@ -662,6 +662,9 @@ g_raid_tr_iostart_raid1(struct g_raid_tr
case BIO_DELETE:
g_raid_iodone(bp, EIO);
break;
+ case BIO_FLUSH:
+ g_raid_tr_flush_common(tr, bp);
+ break;
default:
KASSERT(1 == 0, ("Invalid command here: %u (volume=%s)",
bp->bio_cmd, vol->v_name));
More information about the svn-src-projects
mailing list