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