Date: Sat, 12 Feb 2011 11:00:34 +0000 (UTC) From: Alexander Motin <mav@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r218600 - projects/graid/head/sys/geom/raid Message-ID: <201102121100.p1CB0YrL098717@svn.freebsd.org>
index | next in thread | raw e-mail
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));help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201102121100.p1CB0YrL098717>
