PERFORCE change 125136 for review

Ulf Lilleengen lulf at FreeBSD.org
Tue Aug 14 05:22:38 PDT 2007


http://perforce.freebsd.org/chv.cgi?CH=125136

Change 125136 by lulf at lulf_carrot on 2007/08/14 12:22:18

	- Modify rebuild and parity routines to increase providers access counts
	  before starting and after finishing rebuild instead of doing it for
	  each rebuild bio. This caused the rest of gvinum to lock up while
	  rebuild since the topology lock was aquired all the time.
	- Change output of list to show how far we're in the rebuild process.

Affected files ...

.. //depot/projects/soc2007/lulf/gvinum_fixup/sys/geom/vinum/geom_vinum.c#36 edit
.. //depot/projects/soc2007/lulf/gvinum_fixup/sys/geom/vinum/geom_vinum_init.c#26 edit
.. //depot/projects/soc2007/lulf/gvinum_fixup/sys/geom/vinum/geom_vinum_list.c#6 edit
.. //depot/projects/soc2007/lulf/gvinum_fixup/sys/geom/vinum/geom_vinum_plex.c#28 edit

Differences ...

==== //depot/projects/soc2007/lulf/gvinum_fixup/sys/geom/vinum/geom_vinum.c#36 (text+ko) ====

@@ -745,6 +745,15 @@
 					break;
 				}
 				p->synced = 0;
+				g_topology_assert_not();
+				g_topology_lock();
+				err = gv_access(p->vol_sc->provider, 1, 1, 0);
+				if (err) {
+					printf("VINUM: unable to access "
+					    "provider\n");
+					break;
+				}
+				g_topology_unlock();
 				gv_parity_request(p, GV_BIO_CHECK |
 				    GV_BIO_PARITY, 0);
 				break;
@@ -759,6 +768,15 @@
 					break;
 				}
 				p->synced = 0;
+				g_topology_assert_not();
+				g_topology_lock();
+				err = gv_access(p->vol_sc->provider, 1, 1, 0);
+				if (err) {
+					printf("VINUM: unable to access "
+					    "provider\n");
+					break;
+				}
+				g_topology_unlock();
 				gv_parity_request(p, GV_BIO_CHECK, 0);
 				break;
 

==== //depot/projects/soc2007/lulf/gvinum_fixup/sys/geom/vinum/geom_vinum_init.c#26 (text+ko) ====

@@ -221,6 +221,7 @@
 {
 	struct gv_drive *d;
 	struct gv_sd *s;
+	int error;
 
 /* XXX: Is this safe? (Allows for mounted rebuild)*/
 /*	if (gv_provider_is_open(p->vol_sc->provider))
@@ -245,6 +246,15 @@
 	p->flags |= GV_PLEX_REBUILDING;
 	p->synced = 0;
 
+	g_topology_assert_not();
+	g_topology_lock();
+	error = gv_access(p->vol_sc->provider, 1, 1, 0);
+	if (error) {
+		printf("VINUM: unable to access provider\n");
+		return (0);
+	}
+	g_topology_unlock();
+
 	gv_parity_request(p, GV_BIO_REBUILD, 0);
 	return (0);
 }

==== //depot/projects/soc2007/lulf/gvinum_fixup/sys/geom/vinum/geom_vinum_list.c#6 (text+ko) ====

@@ -294,7 +294,9 @@
 		    p->name, (intmax_t)p->size, (intmax_t)p->size / MEGABYTE);
 		sbuf_printf(sb, "\t\tSubdisks: %8d\n", p->sdcount);
 		sbuf_printf(sb, "\t\tState: %s\n", gv_plexstate(p->state));
-		if ((p->flags & GV_PLEX_SYNCING) || (p->flags & GV_PLEX_GROWING)) {
+		if ((p->flags & GV_PLEX_SYNCING) ||
+		    (p->flags & GV_PLEX_GROWING) ||
+		    (p->flags & GV_PLEX_REBUILDING)) {
 			sbuf_printf(sb, "\t\tSynced: ");
 			sbuf_printf(sb, "%16jd bytes (%d%%)\n",
 			    (intmax_t)p->synced,
@@ -312,7 +314,9 @@
 	} else {
 		sbuf_printf(sb, "P %-18s %2s State: ", p->name,
 		gv_plexorg_short(p->org));
-		if ((p->flags & GV_PLEX_SYNCING) || (p->flags & GV_PLEX_GROWING)) {
+		if ((p->flags & GV_PLEX_SYNCING) ||
+		    (p->flags & GV_PLEX_GROWING) ||
+		    (p->flags & GV_PLEX_REBUILDING)) {
 			sbuf_printf(sb, "S %d%%\t", (int)((p->synced * 100) /
 			    p->size));
 		} else {

==== //depot/projects/soc2007/lulf/gvinum_fixup/sys/geom/vinum/geom_vinum_plex.c#28 (text+ko) ====

@@ -856,27 +856,15 @@
 gv_parity_request(struct gv_plex *p, int flags, off_t offset)
 {
 	struct bio *bp;
-	int error;
 
 	KASSERT(p != NULL, ("gv_parity_request: NULL p"));
 
-	/* Make sure we don't have the lock. */
-	g_topology_assert_not();
-	g_topology_lock();
-	error = gv_access(p->vol_sc->provider, 1, 1, 0);
-	if (error) {
-		printf("VINUM: unable to access provider\n");
-		goto bad;
-	}
-
 	bp = g_new_bio();
 	if (bp == NULL) {
 		printf("VINUM: rebuild of %s failed creating bio: "
 		    "out of memory\n", p->name);
-		gv_access(p->vol_sc->provider, -1, -1, 0);
-		goto bad;
+		return;
 	}
-	g_topology_unlock();
 
 	bp->bio_cmd = BIO_WRITE;
 	bp->bio_done = gv_done;
@@ -903,9 +891,6 @@
 	bp->bio_offset = offset;
 
 	gv_plex_start(p, bp); /* Send it down to the plex. */
-	return;
-bad:
-	g_topology_unlock();
 }
 
 /*
@@ -925,12 +910,13 @@
 		g_free(bp->bio_data);
 	g_destroy_bio(bp);
 
-	/* Make sure we don't have the lock. */
-	g_topology_assert_not();
-	g_topology_lock();
-	gv_access(p->vol_sc->provider, -1, -1, 0);
-	g_topology_unlock();
 	if (error) {
+		/* Make sure we don't have the lock. */
+		g_topology_assert_not();
+		g_topology_lock();
+		gv_access(p->vol_sc->provider, -1, -1, 0);
+		g_topology_unlock();
+
 		if (error == EAGAIN) {
 			printf("VINUM: Parity incorrect at offset 0x%jx\n",
 			    (intmax_t)p->synced);
@@ -942,11 +928,14 @@
 	} else {
 		p->synced += p->stripesize;
 	}
-	printf("VINUM: Parity operation at 0x%jx finished\n",
-	    (intmax_t)p->synced);
 
+	if (p->synced >= p->size) {
+		/* Make sure we don't have the lock. */
+		g_topology_assert_not();
+		g_topology_lock();
+		gv_access(p->vol_sc->provider, -1, -1, 0);
+		g_topology_unlock();
 
-	if (p->synced >= p->size) {
 		/* We're finished. */
 		printf("VINUM: Parity operation on %s finished\n", p->name);
 		p->synced = 0;
@@ -977,12 +966,12 @@
 		g_free(bp->bio_data);
 	g_destroy_bio(bp);
 
-	/* Make sure we don't have the lock. */
-	g_topology_assert_not();
-	g_topology_lock();
-	gv_access(p->vol_sc->provider, -1, -1, 0);
-	g_topology_unlock();
 	if (error) {
+		g_topology_assert_not();
+		g_topology_lock();
+		gv_access(p->vol_sc->provider, -1, -1, 0);
+		g_topology_unlock();
+	
 		printf("VINUM: rebuild of %s failed at offset %jd errno: %d\n",
 		    p->name, (intmax_t)offset, error);
 		p->flags &= ~GV_PLEX_REBUILDING;
@@ -994,6 +983,11 @@
 	offset += (p->stripesize * (gv_sdcount(p, 1) - 1));
 	if (offset >= p->size) {
 		/* We're finished. */
+		g_topology_assert_not();
+		g_topology_lock();
+		gv_access(p->vol_sc->provider, -1, -1, 0);
+		g_topology_unlock();
+	
 		printf("VINUM: rebuild of %s finished\n", p->name);
 		gv_save_config(p->vinumconf);
 		p->flags &= ~GV_PLEX_REBUILDING;


More information about the p4-projects mailing list