p4-projects@freebsd.org
[Top] [All Lists]

PERFORCE change 121973 for review

Subject: PERFORCE change 121973 for review
From: Ulf Lilleengen
Date: Tue, 19 Jun 2007 14:30:20 GMT
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
_______________________________________________
p4-projects@xxxxxxxxxxx mailing list
http://lists.freebsd.org/mailman/listinfo/p4-projects
To unsubscribe, send any mail to "p4-projects-unsubscribe@xxxxxxxxxxx"

<Prev in Thread] Current Thread [Next in Thread>
  • PERFORCE change 121973 for review, Ulf Lilleengen <=