PERFORCE change 121973 for review
Ulf Lilleengen
lulf at FreeBSD.org
Tue Jun 19 14:30:21 UTC 2007
http://perforce.freebsd.org/chv.cgi?CH=121973
Change 121973 by lulf at 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
More information about the p4-projects
mailing list