From owner-p4-projects@FreeBSD.ORG Tue Jun 19 14:30:21 2007 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 1AA4F16A473; Tue, 19 Jun 2007 14:30:21 +0000 (UTC) X-Original-To: perforce@FreeBSD.org Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id DD98F16A46D for ; Tue, 19 Jun 2007 14:30:20 +0000 (UTC) (envelope-from lulf@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [69.147.83.41]) by mx1.freebsd.org (Postfix) with ESMTP id D092E13C4BD for ; Tue, 19 Jun 2007 14:30:20 +0000 (UTC) (envelope-from lulf@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.8/8.13.8) with ESMTP id l5JEUKRo058172 for ; Tue, 19 Jun 2007 14:30:20 GMT (envelope-from lulf@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.8/8.13.8/Submit) id l5JEUKRp058163 for perforce@freebsd.org; Tue, 19 Jun 2007 14:30:20 GMT (envelope-from lulf@FreeBSD.org) Date: Tue, 19 Jun 2007 14:30:20 GMT Message-Id: <200706191430.l5JEUKRp058163@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to lulf@FreeBSD.org using -f From: Ulf Lilleengen To: Perforce Change Reviews Cc: Subject: PERFORCE change 121973 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 19 Jun 2007 14:30:21 -0000 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 #include -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