Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 19 Jun 2007 14:30:20 GMT
From:      Ulf Lilleengen <lulf@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 121973 for review
Message-ID:  <200706191430.l5JEUKRp058163@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=121973

Change 121973 by lulf@lulf_carrot on 2007/06/19 14:29:20

	- Implement delayed write when syncing plexes. This way we can still
	  have the plex mounted and read/write to it when it's syncing.

Affected files ...

.. //depot/projects/soc2007/lulf/gvinum_fixup/sys/geom/vinum/geom_vinum_events.c#3 edit
.. //depot/projects/soc2007/lulf/gvinum_fixup/sys/geom/vinum/geom_vinum_var.h#14 edit
.. //depot/projects/soc2007/lulf/gvinum_fixup/sys/geom/vinum/geom_vinum_volume.c#7 edit

Differences ...

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

@@ -351,6 +351,8 @@
 	v->vinumconf = sc;
 	LIST_INIT(&v->plexes);
 	LIST_INSERT_HEAD(&sc->volumes, v, volume);
+	v->wqueue = g_malloc(sizeof(struct bio_queue_head), M_WAITOK | M_ZERO);
+	bioq_init(v->wqueue);
 }
 
 void

==== //depot/projects/soc2007/lulf/gvinum_fixup/sys/geom/vinum/geom_vinum_var.h#14 (text+ko) ====

@@ -361,6 +361,8 @@
 
 	struct g_provider	*provider;	/* Provider of this volume. */
 
+	struct bio_queue_head	*wqueue;	/* BIO delayed request queue. */
+
 	struct gv_plex	*last_read_plex;
 	struct gv_softc	*vinumconf;	/* Pointer to the vinum config. */
 };

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

@@ -41,7 +41,7 @@
 #include <geom/vinum/geom_vinum_var.h>
 #include <geom/vinum/geom_vinum.h>
 
-static void	gv_sync_complete(struct gv_plex *, struct bio *);
+static int	gv_sync_complete(struct gv_plex *, struct bio *);
 
 void
 gv_volume_start(struct gv_softc *sc, struct bio *bp)
@@ -63,8 +63,14 @@
 		/*
 		 * Try to find a good plex where we can send the request to,
 		 * round-robin-style.  The plex either has to be up, or it's a
-		 * degraded RAID5 plex.
+		 * degraded RAID5 plex. Check if we have delayed requests. Put
+		 * this request on the delayed queue if so. This makes sure that
+		 * we don't read old values.
 		 */
+		if (bioq_first(v->wqueue) != NULL) {
+			bioq_insert_tail(v->wqueue, bp);
+			break;
+		}
 		lp = v->last_read_plex;
 		if (lp == NULL)
 			lp = LIST_FIRST(&v->plexes);
@@ -93,6 +99,14 @@
 
 	case BIO_WRITE:
 	case BIO_DELETE:
+		/* Delay write-requests if any plex is synchronizing. */
+		LIST_FOREACH(p, &v->plexes, in_volume) {
+			if (p->state == GV_PLEX_SYNCING) {
+				bioq_insert_tail(v->wqueue, bp);
+				return;
+			}
+		}
+
 		/* Give the BIO to each plex of this volume. */
 		LIST_FOREACH(p, &v->plexes, in_volume) {
 			if (p->state < GV_PLEX_DEGRADED)
@@ -174,12 +188,13 @@
 /*
  * Handle a finished plex sync bio.
  */
-static void
+static int
 gv_sync_complete(struct gv_plex *to, struct bio *bp)
 {
 	struct gv_plex *from, *p;
 	struct gv_sd *s;
 	struct gv_volume *v;
+	struct gv_softc *sc;
 	int err;
 
 	g_topology_assert_not();
@@ -187,6 +202,7 @@
 	err = 0;
 	from = bp->bio_caller2;
 	v = to->vol_sc;
+	sc = v->vinumconf;
 
 	/* If it was a read, write it. */
 	if (bp->bio_cmd == BIO_READ) {
@@ -210,22 +226,35 @@
 		}
 	}
 	g_destroy_bio(bp);
+	/* Clean up if there was an error. */
 	if (err) {
+		to->flags &= ~GV_PLEX_SYNCING;
 		printf("VINUM: error syncing plexes: error code %d\n", err);
-		return;
 	}
 
 	/* Check if all plexes are synced, and lower refcounts. */
 	g_topology_lock();
 	LIST_FOREACH(p, &v->plexes, in_volume) {
-		if (p->flags & GV_PLEX_SYNCING)
-			goto cleanup;
+		if (p->flags & GV_PLEX_SYNCING) {
+			g_topology_unlock();
+			return (-1);
+		}
 	}
 	/* If we came here, all plexes are synced, and we're free. */
 	gv_access(v->provider, -1, -1, 0);
+	g_topology_unlock();
 	printf("VINUM: plex sync completed\n");
-cleanup:
-	g_topology_unlock();
+
+	/* Issue all delayed requests. */
+	bp = bioq_takefirst(v->wqueue);
+	while (bp != NULL) {
+/*		gv_volume_start(v, bp);*/
+		mtx_lock(&sc->queue_mtx);
+		bioq_disksort(sc->bqueue, bp);
+		mtx_unlock(&sc->queue_mtx);
+		bp = bioq_takefirst(v->wqueue);
+	}
+	return (0);
 }
 
 int



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200706191430.l5JEUKRp058163>