1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2007 Lukas Ertl 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 #include <sys/cdefs.h> 30 #include <sys/param.h> 31 #include <sys/bio.h> 32 #include <sys/lock.h> 33 #include <sys/malloc.h> 34 #include <sys/systm.h> 35 36 #include <geom/geom.h> 37 #include <geom/vinum/geom_vinum_var.h> 38 #include <geom/vinum/geom_vinum.h> 39 40 void 41 gv_volume_flush(struct gv_volume *v) 42 { 43 struct gv_softc *sc; 44 struct bio *bp; 45 46 KASSERT(v != NULL, ("NULL v")); 47 sc = v->vinumconf; 48 KASSERT(sc != NULL, ("NULL sc")); 49 50 bp = bioq_takefirst(v->wqueue); 51 while (bp != NULL) { 52 gv_volume_start(sc, bp); 53 bp = bioq_takefirst(v->wqueue); 54 } 55 } 56 57 void 58 gv_volume_start(struct gv_softc *sc, struct bio *bp) 59 { 60 struct gv_volume *v; 61 struct gv_plex *p, *lp; 62 int numwrites; 63 64 v = bp->bio_to->private; 65 if (v == NULL || v->state != GV_VOL_UP) { 66 g_io_deliver(bp, ENXIO); 67 return; 68 } 69 70 switch (bp->bio_cmd) { 71 case BIO_READ: 72 /* 73 * Try to find a good plex where we can send the request to, 74 * round-robin-style. The plex either has to be up, or it's a 75 * degraded RAID5 plex. Check if we have delayed requests. Put 76 * this request on the delayed queue if so. This makes sure that 77 * we don't read old values. 78 */ 79 if (bioq_first(v->wqueue) != NULL) { 80 bioq_insert_tail(v->wqueue, bp); 81 break; 82 } 83 lp = v->last_read_plex; 84 if (lp == NULL) 85 lp = LIST_FIRST(&v->plexes); 86 p = LIST_NEXT(lp, in_volume); 87 if (p == NULL) 88 p = LIST_FIRST(&v->plexes); 89 do { 90 if (p == NULL) { 91 p = lp; 92 break; 93 } 94 if ((p->state > GV_PLEX_DEGRADED) || 95 (p->state >= GV_PLEX_DEGRADED && 96 p->org == GV_PLEX_RAID5)) 97 break; 98 p = LIST_NEXT(p, in_volume); 99 if (p == NULL) 100 p = LIST_FIRST(&v->plexes); 101 } while (p != lp); 102 103 if ((p == NULL) || 104 (p->org == GV_PLEX_RAID5 && p->state < GV_PLEX_DEGRADED) || 105 (p->org != GV_PLEX_RAID5 && p->state <= GV_PLEX_DEGRADED)) { 106 g_io_deliver(bp, ENXIO); 107 return; 108 } 109 v->last_read_plex = p; 110 111 /* Hand it down to the plex logic. */ 112 gv_plex_start(p, bp); 113 break; 114 115 case BIO_WRITE: 116 case BIO_DELETE: 117 /* Delay write-requests if any plex is synchronizing. */ 118 LIST_FOREACH(p, &v->plexes, in_volume) { 119 if (p->flags & GV_PLEX_SYNCING) { 120 bioq_insert_tail(v->wqueue, bp); 121 return; 122 } 123 } 124 125 numwrites = 0; 126 /* Give the BIO to each plex of this volume. */ 127 LIST_FOREACH(p, &v->plexes, in_volume) { 128 if (p->state < GV_PLEX_DEGRADED) 129 continue; 130 gv_plex_start(p, bp); 131 numwrites++; 132 } 133 if (numwrites == 0) 134 g_io_deliver(bp, ENXIO); 135 break; 136 } 137 } 138 139 void 140 gv_bio_done(struct gv_softc *sc, struct bio *bp) 141 { 142 struct gv_volume *v __diagused; 143 struct gv_plex *p; 144 struct gv_sd *s; 145 146 s = bp->bio_caller1; 147 KASSERT(s != NULL, ("gv_bio_done: NULL s")); 148 p = s->plex_sc; 149 KASSERT(p != NULL, ("gv_bio_done: NULL p")); 150 v = p->vol_sc; 151 KASSERT(v != NULL, ("gv_bio_done: NULL v")); 152 153 switch (p->org) { 154 case GV_PLEX_CONCAT: 155 case GV_PLEX_STRIPED: 156 gv_plex_normal_done(p, bp); 157 break; 158 case GV_PLEX_RAID5: 159 gv_plex_raid5_done(p, bp); 160 break; 161 } 162 163 gv_drive_done(s->drive_sc); 164 } 165