svn commit: r256610 - head/sys/geom/raid

Alexander Motin mav at FreeBSD.org
Wed Oct 16 09:33:25 UTC 2013


Author: mav
Date: Wed Oct 16 09:33:23 2013
New Revision: 256610
URL: http://svnweb.freebsd.org/changeset/base/256610

Log:
  MFprojects/camlock r256445:
  Add unmapped I/O support to GEOM RAID.

Modified:
  head/sys/geom/raid/g_raid.c
  head/sys/geom/raid/g_raid.h
  head/sys/geom/raid/tr_concat.c
  head/sys/geom/raid/tr_raid0.c
  head/sys/geom/raid/tr_raid1.c
  head/sys/geom/raid/tr_raid1e.c
  head/sys/geom/raid/tr_raid5.c

Modified: head/sys/geom/raid/g_raid.c
==============================================================================
--- head/sys/geom/raid/g_raid.c	Wed Oct 16 09:27:51 2013	(r256609)
+++ head/sys/geom/raid/g_raid.c	Wed Oct 16 09:33:23 2013	(r256610)
@@ -993,20 +993,15 @@ g_raid_tr_flush_common(struct g_raid_tr_
 		cbp->bio_caller1 = sd;
 		bioq_insert_tail(&queue, cbp);
 	}
-	for (cbp = bioq_first(&queue); cbp != NULL;
-	    cbp = bioq_first(&queue)) {
-		bioq_remove(&queue, cbp);
+	while ((cbp = bioq_takefirst(&queue)) != NULL) {
 		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);
+	while ((cbp = bioq_takefirst(&queue)) != NULL)
 		g_destroy_bio(cbp);
-	}
 	if (bp->bio_error == 0)
 		bp->bio_error = ENOMEM;
 	g_raid_iodone(bp, bp->bio_error);
@@ -1639,11 +1634,13 @@ static void
 g_raid_launch_provider(struct g_raid_volume *vol)
 {
 	struct g_raid_disk *disk;
+	struct g_raid_subdisk *sd;
 	struct g_raid_softc *sc;
 	struct g_provider *pp;
 	char name[G_RAID_MAX_VOLUMENAME];
 	char   announce_buf[80], buf1[32];
 	off_t off;
+	int i;
 
 	sc = vol->v_softc;
 	sx_assert(&sc->sc_lock, SX_LOCKED);
@@ -1673,6 +1670,17 @@ g_raid_launch_provider(struct g_raid_vol
         }
 
 	pp = g_new_providerf(sc->sc_geom, "%s", name);
+	if (vol->v_tr->tro_class->trc_accept_unmapped) {
+		pp->flags |= G_PF_ACCEPT_UNMAPPED;
+		for (i = 0; i < vol->v_disks_count; i++) {
+			sd = &vol->v_subdisks[i];
+			if (sd->sd_state == G_RAID_SUBDISK_S_NONE)
+				continue;
+			if ((sd->sd_disk->d_consumer->provider->flags &
+			    G_PF_ACCEPT_UNMAPPED) == 0)
+				pp->flags &= ~G_PF_ACCEPT_UNMAPPED;
+		}
+	}
 	pp->private = vol;
 	pp->mediasize = vol->v_mediasize;
 	pp->sectorsize = vol->v_sectorsize;

Modified: head/sys/geom/raid/g_raid.h
==============================================================================
--- head/sys/geom/raid/g_raid.h	Wed Oct 16 09:27:51 2013	(r256609)
+++ head/sys/geom/raid/g_raid.h	Wed Oct 16 09:33:23 2013	(r256610)
@@ -376,6 +376,7 @@ struct g_raid_tr_class {
 	KOBJ_CLASS_FIELDS;
 	int		 trc_enable;
 	int		 trc_priority;
+	int		 trc_accept_unmapped;
 	LIST_ENTRY(g_raid_tr_class) trc_list;
 };
 

Modified: head/sys/geom/raid/tr_concat.c
==============================================================================
--- head/sys/geom/raid/tr_concat.c	Wed Oct 16 09:27:51 2013	(r256609)
+++ head/sys/geom/raid/tr_concat.c	Wed Oct 16 09:33:23 2013	(r256610)
@@ -74,7 +74,8 @@ static struct g_raid_tr_class g_raid_tr_
 	g_raid_tr_concat_methods,
 	sizeof(struct g_raid_tr_concat_object),
 	.trc_enable = 1,
-	.trc_priority = 50
+	.trc_priority = 50,
+	.trc_accept_unmapped = 1
 };
 
 static int
@@ -227,7 +228,10 @@ g_raid_tr_iostart_concat(struct g_raid_t
 
 	offset = bp->bio_offset;
 	remain = bp->bio_length;
-	addr = bp->bio_data;
+	if ((bp->bio_flags & BIO_UNMAPPED) != 0)
+		addr = NULL;
+	else
+		addr = bp->bio_data;
 	no = 0;
 	while (no < vol->v_disks_count &&
 	    offset >= vol->v_subdisks[no].sd_size) {
@@ -244,8 +248,16 @@ g_raid_tr_iostart_concat(struct g_raid_t
 		if (cbp == NULL)
 			goto failure;
 		cbp->bio_offset = offset;
-		cbp->bio_data = addr;
 		cbp->bio_length = length;
+		if ((bp->bio_flags & BIO_UNMAPPED) != 0 &&
+		    bp->bio_cmd != BIO_DELETE) {
+			cbp->bio_ma_offset += (uintptr_t)addr;
+			cbp->bio_ma += cbp->bio_ma_offset / PAGE_SIZE;
+			cbp->bio_ma_offset %= PAGE_SIZE;
+			cbp->bio_ma_n = round_page(cbp->bio_ma_offset +
+			    cbp->bio_length) / PAGE_SIZE;
+		} else
+			cbp->bio_data = addr;
 		cbp->bio_caller1 = sd;
 		bioq_insert_tail(&queue, cbp);
 		remain -= length;
@@ -257,20 +269,15 @@ g_raid_tr_iostart_concat(struct g_raid_t
 		    ("Request ends after volume end (%ju, %ju)",
 			bp->bio_offset, bp->bio_length));
 	} while (remain > 0);
-	for (cbp = bioq_first(&queue); cbp != NULL;
-	    cbp = bioq_first(&queue)) {
-		bioq_remove(&queue, cbp);
+	while ((cbp = bioq_takefirst(&queue)) != NULL) {
 		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);
+	while ((cbp = bioq_takefirst(&queue)) != NULL)
 		g_destroy_bio(cbp);
-	}
 	if (bp->bio_error == 0)
 		bp->bio_error = ENOMEM;
 	g_raid_iodone(bp, bp->bio_error);

Modified: head/sys/geom/raid/tr_raid0.c
==============================================================================
--- head/sys/geom/raid/tr_raid0.c	Wed Oct 16 09:27:51 2013	(r256609)
+++ head/sys/geom/raid/tr_raid0.c	Wed Oct 16 09:33:23 2013	(r256610)
@@ -74,7 +74,8 @@ static struct g_raid_tr_class g_raid_tr_
 	g_raid_tr_raid0_methods,
 	sizeof(struct g_raid_tr_raid0_object),
 	.trc_enable = 1,
-	.trc_priority = 100
+	.trc_priority = 100,
+	.trc_accept_unmapped = 1
 };
 
 static int
@@ -204,7 +205,10 @@ g_raid_tr_iostart_raid0(struct g_raid_tr
 		g_raid_tr_flush_common(tr, bp);
 		return;
 	}
-	addr = bp->bio_data;
+	if ((bp->bio_flags & BIO_UNMAPPED) != 0)
+		addr = NULL;
+	else
+		addr = bp->bio_data;
 	strip_size = vol->v_strip_size;
 
 	/* Stripe number. */
@@ -225,8 +229,16 @@ g_raid_tr_iostart_raid0(struct g_raid_tr
 		if (cbp == NULL)
 			goto failure;
 		cbp->bio_offset = offset + start;
-		cbp->bio_data = addr;
 		cbp->bio_length = length;
+		if ((bp->bio_flags & BIO_UNMAPPED) != 0 &&
+		    bp->bio_cmd != BIO_DELETE) {
+			cbp->bio_ma_offset += (uintptr_t)addr;
+			cbp->bio_ma += cbp->bio_ma_offset / PAGE_SIZE;
+			cbp->bio_ma_offset %= PAGE_SIZE;
+			cbp->bio_ma_n = round_page(cbp->bio_ma_offset +
+			    cbp->bio_length) / PAGE_SIZE;
+		} else
+			cbp->bio_data = addr;
 		cbp->bio_caller1 = &vol->v_subdisks[no];
 		bioq_insert_tail(&queue, cbp);
 		if (++no >= vol->v_disks_count) {
@@ -238,20 +250,15 @@ g_raid_tr_iostart_raid0(struct g_raid_tr
 			addr += length;
 		start = 0;
 	} while (remain > 0);
-	for (cbp = bioq_first(&queue); cbp != NULL;
-	    cbp = bioq_first(&queue)) {
-		bioq_remove(&queue, cbp);
+	while ((cbp = bioq_takefirst(&queue)) != NULL) {
 		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);
+	while ((cbp = bioq_takefirst(&queue)) != NULL)
 		g_destroy_bio(cbp);
-	}
 	if (bp->bio_error == 0)
 		bp->bio_error = ENOMEM;
 	g_raid_iodone(bp, bp->bio_error);

Modified: head/sys/geom/raid/tr_raid1.c
==============================================================================
--- head/sys/geom/raid/tr_raid1.c	Wed Oct 16 09:27:51 2013	(r256609)
+++ head/sys/geom/raid/tr_raid1.c	Wed Oct 16 09:33:23 2013	(r256610)
@@ -130,7 +130,8 @@ static struct g_raid_tr_class g_raid_tr_
 	g_raid_tr_raid1_methods,
 	sizeof(struct g_raid_tr_raid1_object),
 	.trc_enable = 1,
-	.trc_priority = 100
+	.trc_priority = 100,
+	.trc_accept_unmapped = 1
 };
 
 static void g_raid_tr_raid1_rebuild_abort(struct g_raid_tr_object *tr);
@@ -594,20 +595,15 @@ g_raid_tr_iostart_raid1_write(struct g_r
 		cbp->bio_caller1 = sd;
 		bioq_insert_tail(&queue, cbp);
 	}
-	for (cbp = bioq_first(&queue); cbp != NULL;
-	    cbp = bioq_first(&queue)) {
-		bioq_remove(&queue, cbp);
+	while ((cbp = bioq_takefirst(&queue)) != NULL) {
 		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);
+	while ((cbp = bioq_takefirst(&queue)) != NULL)
 		g_destroy_bio(cbp);
-	}
 	if (bp->bio_error == 0)
 		bp->bio_error = ENOMEM;
 	g_raid_iodone(bp, bp->bio_error);

Modified: head/sys/geom/raid/tr_raid1e.c
==============================================================================
--- head/sys/geom/raid/tr_raid1e.c	Wed Oct 16 09:27:51 2013	(r256609)
+++ head/sys/geom/raid/tr_raid1e.c	Wed Oct 16 09:33:23 2013	(r256610)
@@ -134,7 +134,8 @@ static struct g_raid_tr_class g_raid_tr_
 	g_raid_tr_raid1e_methods,
 	sizeof(struct g_raid_tr_raid1e_object),
 	.trc_enable = 1,
-	.trc_priority = 200
+	.trc_priority = 200,
+	.trc_accept_unmapped = 1
 };
 
 static void g_raid_tr_raid1e_rebuild_abort(struct g_raid_tr_object *tr);
@@ -701,7 +702,10 @@ g_raid_tr_iostart_raid1e_read(struct g_r
 	int best;
 
 	vol = tr->tro_volume;
-	addr = bp->bio_data;
+	if ((bp->bio_flags & BIO_UNMAPPED) != 0)
+		addr = NULL;
+	else
+		addr = bp->bio_data;
 	strip_size = vol->v_strip_size;
 	V2P(vol, bp->bio_offset, &no, &offset, &start);
 	remain = bp->bio_length;
@@ -721,8 +725,15 @@ g_raid_tr_iostart_raid1e_read(struct g_r
 		if (cbp == NULL)
 			goto failure;
 		cbp->bio_offset = offset + start;
-		cbp->bio_data = addr;
 		cbp->bio_length = length;
+		if ((bp->bio_flags & BIO_UNMAPPED) != 0) {
+			cbp->bio_ma_offset += (uintptr_t)addr;
+			cbp->bio_ma += cbp->bio_ma_offset / PAGE_SIZE;
+			cbp->bio_ma_offset %= PAGE_SIZE;
+			cbp->bio_ma_n = round_page(cbp->bio_ma_offset +
+			    cbp->bio_length) / PAGE_SIZE;
+		} else
+			cbp->bio_data = addr;
 		cbp->bio_caller1 = &vol->v_subdisks[no];
 		bioq_insert_tail(&queue, cbp);
 		no += N - best;
@@ -734,20 +745,15 @@ g_raid_tr_iostart_raid1e_read(struct g_r
 		addr += length;
 		start = 0;
 	}
-	for (cbp = bioq_first(&queue); cbp != NULL;
-	    cbp = bioq_first(&queue)) {
-		bioq_remove(&queue, cbp);
+	while ((cbp = bioq_takefirst(&queue)) != NULL) {
 		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);
+	while ((cbp = bioq_takefirst(&queue)) != NULL)
 		g_destroy_bio(cbp);
-	}
 	if (bp->bio_error == 0)
 		bp->bio_error = ENOMEM;
 	g_raid_iodone(bp, bp->bio_error);
@@ -766,7 +772,10 @@ g_raid_tr_iostart_raid1e_write(struct g_
 	int i;
 
 	vol = tr->tro_volume;
-	addr = bp->bio_data;
+	if ((bp->bio_flags & BIO_UNMAPPED) != 0)
+		addr = NULL;
+	else
+		addr = bp->bio_data;
 	strip_size = vol->v_strip_size;
 	V2P(vol, bp->bio_offset, &no, &offset, &start);
 	remain = bp->bio_length;
@@ -791,8 +800,16 @@ g_raid_tr_iostart_raid1e_write(struct g_
 			if (cbp == NULL)
 				goto failure;
 			cbp->bio_offset = offset + start;
-			cbp->bio_data = addr;
 			cbp->bio_length = length;
+			if ((bp->bio_flags & BIO_UNMAPPED) != 0 &&
+			    bp->bio_cmd != BIO_DELETE) {
+				cbp->bio_ma_offset += (uintptr_t)addr;
+				cbp->bio_ma += cbp->bio_ma_offset / PAGE_SIZE;
+				cbp->bio_ma_offset %= PAGE_SIZE;
+				cbp->bio_ma_n = round_page(cbp->bio_ma_offset +
+				    cbp->bio_length) / PAGE_SIZE;
+			} else
+				cbp->bio_data = addr;
 			cbp->bio_caller1 = sd;
 			bioq_insert_tail(&queue, cbp);
 nextdisk:
@@ -806,20 +823,15 @@ nextdisk:
 			addr += length;
 		start = 0;
 	}
-	for (cbp = bioq_first(&queue); cbp != NULL;
-	    cbp = bioq_first(&queue)) {
-		bioq_remove(&queue, cbp);
+	while ((cbp = bioq_takefirst(&queue)) != NULL) {
 		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);
+	while ((cbp = bioq_takefirst(&queue)) != NULL)
 		g_destroy_bio(cbp);
-	}
 	if (bp->bio_error == 0)
 		bp->bio_error = ENOMEM;
 	g_raid_iodone(bp, bp->bio_error);
@@ -1030,6 +1042,9 @@ rebuild_round_done:
 			cbp->bio_offset = offset + start;
 			cbp->bio_length = bp->bio_length;
 			cbp->bio_data = bp->bio_data;
+			cbp->bio_ma = bp->bio_ma;
+			cbp->bio_ma_offset = bp->bio_ma_offset;
+			cbp->bio_ma_n = bp->bio_ma_n;
 			g_destroy_bio(bp);
 			nsd = &vol->v_subdisks[disk];
 			G_RAID_LOGREQ(2, cbp, "Retrying read from %d",

Modified: head/sys/geom/raid/tr_raid5.c
==============================================================================
--- head/sys/geom/raid/tr_raid5.c	Wed Oct 16 09:27:51 2013	(r256609)
+++ head/sys/geom/raid/tr_raid5.c	Wed Oct 16 09:33:23 2013	(r256610)
@@ -324,20 +324,15 @@ g_raid_tr_iostart_raid5_read(struct g_ra
 		addr += length;
 		start = 0;
 	} while (remain > 0);
-	for (cbp = bioq_first(&queue); cbp != NULL;
-	    cbp = bioq_first(&queue)) {
-		bioq_remove(&queue, cbp);
+	while ((cbp = bioq_takefirst(&queue)) != NULL) {
 		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);
+	while ((cbp = bioq_takefirst(&queue)) != NULL)
 		g_destroy_bio(cbp);
-	}
 	if (bp->bio_error == 0)
 		bp->bio_error = ENOMEM;
 	g_raid_iodone(bp, bp->bio_error);


More information about the svn-src-head mailing list