2 * Copyright (c) 2004, 2007 Lukas Ertl
3 * Copyright (c) 2007, 2009 Ulf Lilleengen
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 #include <sys/cdefs.h>
29 __FBSDID("$FreeBSD$");
31 #include <sys/param.h>
34 #include <sys/malloc.h>
35 #include <sys/systm.h>
37 #include <geom/geom.h>
38 #include <geom/vinum/geom_vinum_var.h>
39 #include <geom/vinum/geom_vinum_raid5.h>
40 #include <geom/vinum/geom_vinum.h>
42 static int gv_check_parity(struct gv_plex *, struct bio *,
43 struct gv_raid5_packet *);
44 static int gv_normal_parity(struct gv_plex *, struct bio *,
45 struct gv_raid5_packet *);
46 static void gv_plex_flush(struct gv_plex *);
47 static int gv_plex_offset(struct gv_plex *, off_t, off_t, off_t *, off_t *,
49 static int gv_plex_normal_request(struct gv_plex *, struct bio *, off_t,
51 static void gv_post_bio(struct gv_softc *, struct bio *);
54 gv_plex_start(struct gv_plex *p, struct bio *bp)
58 struct gv_raid5_packet *wp;
60 off_t bcount, boff, len;
62 bcount = bp->bio_length;
64 boff = bp->bio_offset;
66 /* Walk over the whole length of the request, we might split it up. */
71 * RAID5 plexes need special treatment, as a single request
72 * might involve several read/write sub-requests.
74 if (p->org == GV_PLEX_RAID5) {
75 wp = gv_raid5_start(p, bp, addr, boff, bcount);
81 if (TAILQ_EMPTY(&wp->bits))
83 else if (wp->lockbase != -1)
84 TAILQ_INSERT_TAIL(&p->packets, wp, list);
87 * Requests to concatenated and striped plexes go straight
91 len = gv_plex_normal_request(p, bp, boff, bcount, addr);
102 * Fire off all sub-requests. We get the correct consumer (== drive)
103 * to send each request to via the subdisk that was stored in
106 cbp = bioq_takefirst(p->bqueue);
107 while (cbp != NULL) {
109 * RAID5 sub-requests need to come in correct order, otherwise
110 * we trip over the parity, as it might be overwritten by
111 * another sub-request. We abuse cbp->bio_caller2 to mark
112 * potential overlap situations.
114 if (cbp->bio_caller2 != NULL && gv_stripe_active(p, cbp)) {
115 /* Park the bio on the waiting queue. */
116 cbp->bio_pflags |= GV_BIO_ONHOLD;
117 bioq_disksort(p->wqueue, cbp);
119 s = cbp->bio_caller1;
120 g_io_request(cbp, s->drive_sc->consumer);
122 cbp = bioq_takefirst(p->bqueue);
127 gv_plex_offset(struct gv_plex *p, off_t boff, off_t bcount, off_t *real_off,
128 off_t *real_len, int *sdno, int growing)
132 off_t len_left, stripeend, stripeno, stripestart;
137 * Find the subdisk where this request starts. The subdisks in
138 * this list must be ordered by plex_offset.
141 LIST_FOREACH(s, &p->subdisks, in_plex) {
142 if (s->plex_offset <= boff &&
143 s->plex_offset + s->size > boff) {
149 if (s == NULL || s->drive_sc == NULL)
150 return (GV_ERR_NOTFOUND);
152 /* Calculate corresponding offsets on disk. */
153 *real_off = boff - s->plex_offset;
154 len_left = s->size - (*real_off);
155 KASSERT(len_left >= 0, ("gv_plex_offset: len_left < 0"));
156 *real_len = (bcount > len_left) ? len_left : bcount;
159 case GV_PLEX_STRIPED:
160 /* The number of the stripe where the request starts. */
161 stripeno = boff / p->stripesize;
162 KASSERT(stripeno >= 0, ("gv_plex_offset: stripeno < 0"));
164 /* Take growing subdisks into account when calculating. */
165 sdcount = gv_sdcount(p, (boff >= p->synced));
167 if (!(boff + bcount <= p->synced) &&
168 (p->flags & GV_PLEX_GROWING) &&
170 return (GV_ERR_ISBUSY);
171 *sdno = stripeno % sdcount;
173 KASSERT(sdno >= 0, ("gv_plex_offset: sdno < 0"));
174 stripestart = (stripeno / sdcount) *
176 KASSERT(stripestart >= 0, ("gv_plex_offset: stripestart < 0"));
177 stripeend = stripestart + p->stripesize;
178 *real_off = boff - (stripeno * p->stripesize) +
180 len_left = stripeend - *real_off;
181 KASSERT(len_left >= 0, ("gv_plex_offset: len_left < 0"));
183 *real_len = (bcount <= len_left) ? bcount : len_left;
187 return (GV_ERR_PLEXORG);
193 * Prepare a normal plex request.
196 gv_plex_normal_request(struct gv_plex *p, struct bio *bp, off_t boff,
197 off_t bcount, caddr_t addr)
201 off_t real_len, real_off;
206 real_len = real_off = 0;
210 if (p == NULL || LIST_EMPTY(&p->subdisks))
213 err = gv_plex_offset(p, boff, bcount, &real_off,
214 &real_len, &sdno, (bp->bio_pflags & GV_BIO_GROW));
215 /* If the request was blocked, put it into wait. */
216 if (err == GV_ERR_ISBUSY) {
217 bioq_disksort(p->rqueue, bp);
218 return (-1); /* "Fail", and delay request. */
226 /* Find the right subdisk. */
228 LIST_FOREACH(s, &p->subdisks, in_plex) {
234 /* Subdisk not found. */
235 if (s == NULL || s->drive_sc == NULL)
238 /* Now check if we can handle the request on this subdisk. */
241 /* If the subdisk is up, just continue. */
244 if (bp->bio_pflags & GV_BIO_INTERNAL)
245 G_VINUM_DEBUG(0, "subdisk must be in the stale state in"
246 " order to perform administrative requests");
249 if (!(bp->bio_pflags & GV_BIO_SYNCREQ)) {
250 G_VINUM_DEBUG(0, "subdisk stale, unable to perform "
255 G_VINUM_DEBUG(1, "sd %s is initializing", s->name);
256 gv_set_sd_state(s, GV_SD_INITIALIZING, GV_SETSTATE_FORCE);
258 case GV_SD_INITIALIZING:
259 if (bp->bio_cmd == BIO_READ)
263 /* All other subdisk states mean it's not accessible. */
267 /* Clone the bio and adjust the offsets and sizes. */
268 cbp = g_clone_bio(bp);
273 cbp->bio_offset = real_off + s->drive_offset;
274 cbp->bio_length = real_len;
275 cbp->bio_data = addr;
276 cbp->bio_done = gv_done;
277 cbp->bio_caller1 = s;
279 /* Store the sub-requests now and let others issue them. */
280 bioq_insert_tail(p->bqueue, cbp);
283 G_VINUM_LOGREQ(0, bp, "plex request failed.");
284 /* Building the sub-request failed. If internal BIO, do not deliver. */
285 if (bp->bio_pflags & GV_BIO_INTERNAL) {
286 if (bp->bio_pflags & GV_BIO_MALLOC)
287 g_free(bp->bio_data);
289 p->flags &= ~(GV_PLEX_SYNCING | GV_PLEX_REBUILDING |
293 g_io_deliver(bp, err);
298 * Handle a completed request to a striped or concatenated plex.
301 gv_plex_normal_done(struct gv_plex *p, struct bio *bp)
305 pbp = bp->bio_parent;
306 if (pbp->bio_error == 0)
307 pbp->bio_error = bp->bio_error;
310 if (pbp->bio_children == pbp->bio_inbed) {
311 /* Just set it to length since multiple plexes will
312 * screw things up. */
313 pbp->bio_completed = pbp->bio_length;
314 if (pbp->bio_pflags & GV_BIO_SYNCREQ)
315 gv_sync_complete(p, pbp);
316 else if (pbp->bio_pflags & GV_BIO_GROW)
317 gv_grow_complete(p, pbp);
319 g_io_deliver(pbp, pbp->bio_error);
324 * Handle a completed request to a RAID-5 plex.
327 gv_plex_raid5_done(struct gv_plex *p, struct bio *bp)
330 struct bio *cbp, *pbp;
331 struct gv_bioq *bq, *bq2;
332 struct gv_raid5_packet *wp;
338 wp = bp->bio_caller2;
340 switch (bp->bio_parent->bio_cmd) {
343 completed = bp->bio_completed;
347 TAILQ_FOREACH_SAFE(bq, &wp->bits, queue, bq2) {
350 TAILQ_REMOVE(&wp->bits, bq, queue);
352 for (i = 0; i < wp->length; i++)
353 wp->data[i] ^= bp->bio_data[i];
356 if (TAILQ_EMPTY(&wp->bits)) {
357 completed = wp->length;
358 if (wp->lockbase != -1) {
359 TAILQ_REMOVE(&p->packets, wp, list);
360 /* Bring the waiting bios back into the game. */
361 pbp = bioq_takefirst(p->wqueue);
362 while (pbp != NULL) {
363 gv_post_bio(sc, pbp);
364 pbp = bioq_takefirst(p->wqueue);
373 /* XXX can this ever happen? */
375 completed = bp->bio_completed;
379 /* Check if we need to handle parity data. */
380 TAILQ_FOREACH_SAFE(bq, &wp->bits, queue, bq2) {
383 TAILQ_REMOVE(&wp->bits, bq, queue);
387 for (i = 0; i < wp->length; i++)
388 cbp->bio_data[i] ^= bp->bio_data[i];
393 /* Handle parity data. */
394 if (TAILQ_EMPTY(&wp->bits)) {
395 if (bp->bio_parent->bio_pflags & GV_BIO_CHECK)
396 i = gv_check_parity(p, bp, wp);
398 i = gv_normal_parity(p, bp, wp);
400 /* All of our sub-requests have finished. */
402 completed = wp->length;
403 TAILQ_REMOVE(&p->packets, wp, list);
404 /* Bring the waiting bios back into the game. */
405 pbp = bioq_takefirst(p->wqueue);
406 while (pbp != NULL) {
407 gv_post_bio(sc, pbp);
408 pbp = bioq_takefirst(p->wqueue);
417 pbp = bp->bio_parent;
418 if (pbp->bio_error == 0)
419 pbp->bio_error = bp->bio_error;
420 pbp->bio_completed += completed;
422 /* When the original request is finished, we deliver it. */
424 if (pbp->bio_inbed == pbp->bio_children) {
425 /* Hand it over for checking or delivery. */
426 if (pbp->bio_cmd == BIO_WRITE &&
427 (pbp->bio_pflags & GV_BIO_CHECK)) {
428 gv_parity_complete(p, pbp);
429 } else if (pbp->bio_cmd == BIO_WRITE &&
430 (pbp->bio_pflags & GV_BIO_REBUILD)) {
431 gv_rebuild_complete(p, pbp);
432 } else if (pbp->bio_pflags & GV_BIO_INIT) {
433 gv_init_complete(p, pbp);
434 } else if (pbp->bio_pflags & GV_BIO_SYNCREQ) {
435 gv_sync_complete(p, pbp);
436 } else if (pbp->bio_pflags & GV_BIO_GROW) {
437 gv_grow_complete(p, pbp);
439 g_io_deliver(pbp, pbp->bio_error);
443 /* Clean up what we allocated. */
444 if (bp->bio_cflags & GV_BIO_MALLOC)
445 g_free(bp->bio_data);
450 gv_check_parity(struct gv_plex *p, struct bio *bp, struct gv_raid5_packet *wp)
454 int err, finished, i;
459 if (wp->waiting != NULL) {
462 s = pbp->bio_caller1;
463 g_io_request(pbp, s->drive_sc->consumer);
466 } else if (wp->parity != NULL) {
470 /* Check if the parity is correct. */
471 for (i = 0; i < wp->length; i++) {
472 if (bp->bio_data[i] != pbp->bio_data[i]) {
478 /* The parity is not correct... */
480 bp->bio_parent->bio_error = EAGAIN;
482 /* ... but we rebuild it. */
483 if (bp->bio_parent->bio_pflags & GV_BIO_PARITY) {
484 s = pbp->bio_caller1;
485 g_io_request(pbp, s->drive_sc->consumer);
491 * Clean up the BIO we would have used for rebuilding the
495 bp->bio_parent->bio_inbed++;
505 gv_normal_parity(struct gv_plex *p, struct bio *bp, struct gv_raid5_packet *wp)
507 struct bio *cbp, *pbp;
513 if (wp->waiting != NULL) {
517 for (i = 0; i < wp->length; i++)
518 cbp->bio_data[i] ^= pbp->bio_data[i];
519 s = pbp->bio_caller1;
520 g_io_request(pbp, s->drive_sc->consumer);
523 } else if (wp->parity != NULL) {
526 s = cbp->bio_caller1;
527 g_io_request(cbp, s->drive_sc->consumer);
534 /* Flush the queue with delayed requests. */
536 gv_plex_flush(struct gv_plex *p)
542 bp = bioq_takefirst(p->rqueue);
544 gv_plex_start(p, bp);
545 bp = bioq_takefirst(p->rqueue);
550 gv_post_bio(struct gv_softc *sc, struct bio *bp)
553 KASSERT(sc != NULL, ("NULL sc"));
554 KASSERT(bp != NULL, ("NULL bp"));
555 mtx_lock(&sc->bqueue_mtx);
556 bioq_disksort(sc->bqueue_down, bp);
558 mtx_unlock(&sc->bqueue_mtx);
562 gv_sync_request(struct gv_plex *from, struct gv_plex *to, off_t offset,
563 off_t length, int type, caddr_t data)
568 KASSERT(from != NULL, ("NULL from"));
569 KASSERT(to != NULL, ("NULL to"));
570 sc = from->vinumconf;
571 KASSERT(sc != NULL, ("NULL sc"));
575 G_VINUM_DEBUG(0, "sync from '%s' failed at offset "
576 " %jd; out of memory", from->name, offset);
579 bp->bio_length = length;
580 bp->bio_done = gv_done;
581 bp->bio_pflags |= GV_BIO_SYNCREQ;
582 bp->bio_offset = offset;
583 bp->bio_caller1 = from;
584 bp->bio_caller2 = to;
587 data = g_malloc(length, M_WAITOK);
588 bp->bio_pflags |= GV_BIO_MALLOC; /* Free on the next run. */
591 /* Send down next. */
593 //gv_plex_start(from, bp);
598 * Handle a finished plex sync bio.
601 gv_sync_complete(struct gv_plex *to, struct bio *bp)
603 struct gv_plex *from, *p;
610 g_topology_assert_not();
613 KASSERT(to != NULL, ("NULL to"));
614 KASSERT(bp != NULL, ("NULL bp"));
615 from = bp->bio_caller2;
616 KASSERT(from != NULL, ("NULL from"));
618 KASSERT(v != NULL, ("NULL v"));
620 KASSERT(sc != NULL, ("NULL sc"));
622 /* If it was a read, write it. */
623 if (bp->bio_cmd == BIO_READ) {
624 err = gv_sync_request(from, to, bp->bio_offset, bp->bio_length,
625 BIO_WRITE, bp->bio_data);
626 /* If it was a write, read the next one. */
627 } else if (bp->bio_cmd == BIO_WRITE) {
628 if (bp->bio_pflags & GV_BIO_MALLOC)
629 g_free(bp->bio_data);
630 to->synced += bp->bio_length;
631 /* If we're finished, clean up. */
632 if (bp->bio_offset + bp->bio_length >= from->size) {
633 G_VINUM_DEBUG(1, "syncing of %s from %s completed",
634 to->name, from->name);
635 /* Update our state. */
636 LIST_FOREACH(s, &to->subdisks, in_plex)
637 gv_set_sd_state(s, GV_SD_UP, 0);
638 gv_update_plex_state(to);
639 to->flags &= ~GV_PLEX_SYNCING;
641 gv_post_event(sc, GV_EVENT_SAVE_CONFIG, sc, NULL, 0, 0);
643 offset = bp->bio_offset + bp->bio_length;
644 err = gv_sync_request(from, to, offset,
645 MIN(bp->bio_length, from->size - offset),
650 /* Clean up if there was an error. */
652 to->flags &= ~GV_PLEX_SYNCING;
653 G_VINUM_DEBUG(0, "error syncing plexes: error code %d", err);
656 /* Check if all plexes are synced, and lower refcounts. */
658 LIST_FOREACH(p, &v->plexes, in_volume) {
659 if (p->flags & GV_PLEX_SYNCING) {
664 /* If we came here, all plexes are synced, and we're free. */
665 gv_access(v->provider, -1, -1, 0);
667 G_VINUM_DEBUG(1, "plex sync completed");
673 * Create a new bio struct for the next grow request.
676 gv_grow_request(struct gv_plex *p, off_t offset, off_t length, int type,
682 KASSERT(p != NULL, ("gv_grow_request: NULL p"));
684 KASSERT(sc != NULL, ("gv_grow_request: NULL sc"));
688 G_VINUM_DEBUG(0, "grow of %s failed creating bio: "
689 "out of memory", p->name);
694 bp->bio_done = gv_done;
697 bp->bio_offset = offset;
698 bp->bio_length = length;
699 bp->bio_pflags |= GV_BIO_GROW;
701 data = g_malloc(length, M_WAITOK);
702 bp->bio_pflags |= GV_BIO_MALLOC;
706 //gv_plex_start(p, bp);
711 * Finish handling of a bio to a growing plex.
714 gv_grow_complete(struct gv_plex *p, struct bio *bp)
719 off_t origsize, offset;
723 KASSERT(v != NULL, ("gv_grow_complete: NULL v"));
725 KASSERT(sc != NULL, ("gv_grow_complete: NULL sc"));
728 /* If it was a read, write it. */
729 if (bp->bio_cmd == BIO_READ) {
730 p->synced += bp->bio_length;
731 err = gv_grow_request(p, bp->bio_offset, bp->bio_length,
732 BIO_WRITE, bp->bio_data);
733 /* If it was a write, read next. */
734 } else if (bp->bio_cmd == BIO_WRITE) {
735 if (bp->bio_pflags & GV_BIO_MALLOC)
736 g_free(bp->bio_data);
738 /* Find the real size of the plex. */
739 sdcount = gv_sdcount(p, 1);
740 s = LIST_FIRST(&p->subdisks);
741 KASSERT(s != NULL, ("NULL s"));
742 origsize = (s->size * (sdcount - 1));
743 if (bp->bio_offset + bp->bio_length >= origsize) {
744 G_VINUM_DEBUG(1, "growing of %s completed", p->name);
745 p->flags &= ~GV_PLEX_GROWING;
746 LIST_FOREACH(s, &p->subdisks, in_plex) {
747 s->flags &= ~GV_SD_GROW;
748 gv_set_sd_state(s, GV_SD_UP, 0);
750 p->size = gv_plex_size(p);
751 gv_update_vol_size(v, gv_vol_size(v));
752 gv_set_plex_state(p, GV_PLEX_UP, 0);
754 gv_access(v->provider, -1, -1, 0);
757 gv_post_event(sc, GV_EVENT_SAVE_CONFIG, sc, NULL, 0, 0);
758 /* Issue delayed requests. */
761 offset = bp->bio_offset + bp->bio_length;
762 err = gv_grow_request(p, offset,
763 MIN(bp->bio_length, origsize - offset),
770 p->flags &= ~GV_PLEX_GROWING;
771 G_VINUM_DEBUG(0, "error growing plex: error code %d", err);
777 * Create an initialization BIO and send it off to the consumer. Assume that
778 * we're given initialization data as parameter.
781 gv_init_request(struct gv_sd *s, off_t start, caddr_t data, off_t length)
784 struct g_consumer *cp;
785 struct bio *bp, *cbp;
787 KASSERT(s != NULL, ("gv_init_request: NULL s"));
789 KASSERT(d != NULL, ("gv_init_request: NULL d"));
791 KASSERT(cp != NULL, ("gv_init_request: NULL cp"));
795 G_VINUM_DEBUG(0, "subdisk '%s' init: write failed at offset %jd"
796 " (drive offset %jd); out of memory", s->name,
797 (intmax_t)s->initialized, (intmax_t)start);
798 return; /* XXX: Error codes. */
800 bp->bio_cmd = BIO_WRITE;
802 bp->bio_done = gv_done;
804 bp->bio_length = length;
805 bp->bio_pflags |= GV_BIO_INIT;
806 bp->bio_offset = start;
809 /* Then ofcourse, we have to clone it. */
810 cbp = g_clone_bio(bp);
812 G_VINUM_DEBUG(0, "subdisk '%s' init: write failed at offset %jd"
813 " (drive offset %jd); out of memory", s->name,
814 (intmax_t)s->initialized, (intmax_t)start);
815 return; /* XXX: Error codes. */
817 cbp->bio_done = gv_done;
818 cbp->bio_caller1 = s;
819 /* Send it off to the consumer. */
820 g_io_request(cbp, cp);
824 * Handle a finished initialization BIO.
827 gv_init_complete(struct gv_plex *p, struct bio *bp)
831 struct g_consumer *cp;
838 start = bp->bio_offset;
839 length = bp->bio_length;
840 error = bp->bio_error;
843 KASSERT(s != NULL, ("gv_init_complete: NULL s"));
845 KASSERT(d != NULL, ("gv_init_complete: NULL d"));
847 KASSERT(cp != NULL, ("gv_init_complete: NULL cp"));
849 KASSERT(sc != NULL, ("gv_init_complete: NULL sc"));
854 * First we need to find out if it was okay, and abort if it's not.
855 * Then we need to free previous buffers, find out the correct subdisk,
856 * as well as getting the correct starting point and length of the BIO.
858 if (start >= s->drive_offset + s->size) {
859 /* Free the data we initialized. */
862 g_topology_assert_not();
864 g_access(cp, 0, -1, 0);
867 gv_set_sd_state(s, GV_SD_STALE, GV_SETSTATE_FORCE |
870 gv_set_sd_state(s, GV_SD_UP, GV_SETSTATE_CONFIG);
872 gv_post_event(sc, GV_EVENT_SAVE_CONFIG, sc, NULL, 0, 0);
873 G_VINUM_DEBUG(1, "subdisk '%s' init: finished "
874 "successfully", s->name);
878 s->initialized += length;
880 gv_init_request(s, start, data, length);
884 * Create a new bio struct for the next parity rebuild. Used both by internal
885 * rebuild of degraded plexes as well as user initiated rebuilds/checks.
888 gv_parity_request(struct gv_plex *p, int flags, off_t offset)
893 KASSERT(p != NULL, ("gv_parity_request: NULL p"));
895 KASSERT(sc != NULL, ("gv_parity_request: NULL sc"));
899 G_VINUM_DEBUG(0, "rebuild of %s failed creating bio: "
900 "out of memory", p->name);
904 bp->bio_cmd = BIO_WRITE;
905 bp->bio_done = gv_done;
907 bp->bio_length = p->stripesize;
911 * Check if it's a rebuild of a degraded plex or a user request of
914 if (flags & GV_BIO_REBUILD)
915 bp->bio_data = g_malloc(GV_DFLT_SYNCSIZE, M_WAITOK);
916 else if (flags & GV_BIO_CHECK)
917 bp->bio_data = g_malloc(p->stripesize, M_WAITOK | M_ZERO);
919 G_VINUM_DEBUG(0, "invalid flags given in rebuild");
923 bp->bio_pflags = flags;
924 bp->bio_pflags |= GV_BIO_MALLOC;
926 /* We still have more parity to build. */
927 bp->bio_offset = offset;
929 //gv_plex_start(p, bp); /* Send it down to the plex. */
933 * Handle a finished parity write.
936 gv_parity_complete(struct gv_plex *p, struct bio *bp)
941 error = bp->bio_error;
942 flags = bp->bio_pflags;
943 flags &= ~GV_BIO_MALLOC;
946 KASSERT(sc != NULL, ("gv_parity_complete: NULL sc"));
948 /* Clean up what we allocated. */
949 if (bp->bio_pflags & GV_BIO_MALLOC)
950 g_free(bp->bio_data);
953 if (error == EAGAIN) {
954 G_VINUM_DEBUG(0, "parity incorrect at offset 0x%jx",
955 (intmax_t)p->synced);
958 /* Any error is fatal, except EAGAIN when we're rebuilding. */
959 if (error && !(error == EAGAIN && (flags & GV_BIO_PARITY))) {
960 /* Make sure we don't have the lock. */
961 g_topology_assert_not();
963 gv_access(p->vol_sc->provider, -1, -1, 0);
965 G_VINUM_DEBUG(0, "parity check on %s failed at 0x%jx "
966 "errno %d", p->name, (intmax_t)p->synced, error);
969 p->synced += p->stripesize;
972 if (p->synced >= p->size) {
973 /* Make sure we don't have the lock. */
974 g_topology_assert_not();
976 gv_access(p->vol_sc->provider, -1, -1, 0);
978 /* We're finished. */
979 G_VINUM_DEBUG(1, "parity operation on %s finished", p->name);
981 gv_post_event(sc, GV_EVENT_SAVE_CONFIG, sc, NULL, 0, 0);
985 /* Send down next. It will determine if we need to itself. */
986 gv_parity_request(p, flags, p->synced);
990 * Handle a finished plex rebuild bio.
993 gv_rebuild_complete(struct gv_plex *p, struct bio *bp)
1000 error = bp->bio_error;
1001 flags = bp->bio_pflags;
1002 offset = bp->bio_offset;
1003 flags &= ~GV_BIO_MALLOC;
1005 KASSERT(sc != NULL, ("gv_rebuild_complete: NULL sc"));
1007 /* Clean up what we allocated. */
1008 if (bp->bio_pflags & GV_BIO_MALLOC)
1009 g_free(bp->bio_data);
1013 g_topology_assert_not();
1015 gv_access(p->vol_sc->provider, -1, -1, 0);
1016 g_topology_unlock();
1018 G_VINUM_DEBUG(0, "rebuild of %s failed at offset %jd errno: %d",
1019 p->name, (intmax_t)offset, error);
1020 p->flags &= ~GV_PLEX_REBUILDING;
1022 gv_plex_flush(p); /* Flush out remaining rebuild BIOs. */
1026 offset += (p->stripesize * (gv_sdcount(p, 1) - 1));
1027 if (offset >= p->size) {
1028 /* We're finished. */
1029 g_topology_assert_not();
1031 gv_access(p->vol_sc->provider, -1, -1, 0);
1032 g_topology_unlock();
1034 G_VINUM_DEBUG(1, "rebuild of %s finished", p->name);
1035 gv_save_config(p->vinumconf);
1036 p->flags &= ~GV_PLEX_REBUILDING;
1038 /* Try to up all subdisks. */
1039 LIST_FOREACH(s, &p->subdisks, in_plex)
1040 gv_update_sd_state(s);
1041 gv_post_event(sc, GV_EVENT_SAVE_CONFIG, sc, NULL, 0, 0);
1042 gv_plex_flush(p); /* Flush out remaining rebuild BIOs. */
1046 /* Send down next. It will determine if we need to itself. */
1047 gv_parity_request(p, flags, offset);