PERFORCE change 120381 for review
Ulf Lilleengen
lulf at FreeBSD.org
Fri May 25 13:34:22 UTC 2007
http://perforce.freebsd.org/chv.cgi?CH=120381
Change 120381 by lulf at lulf_carrot on 2007/05/25 13:34:04
- Add error handling to the parity checking.
- Call gv_access before we issue bio's since we need to actually get
permission to read/write to the consumers.
- Reset access counters when calling gv_parity_completed.
- Add topology locking where needed. Might change the scheme for this
later.
- Make gv_access availiable to other functions.
Affected files ...
.. //depot/projects/soc2007/lulf/gvinum_fixup/sys/geom/vinum/geom_vinum.c#11 edit
.. //depot/projects/soc2007/lulf/gvinum_fixup/sys/geom/vinum/geom_vinum.h#9 edit
.. //depot/projects/soc2007/lulf/gvinum_fixup/sys/geom/vinum/geom_vinum_plex.c#6 edit
Differences ...
==== //depot/projects/soc2007/lulf/gvinum_fixup/sys/geom/vinum/geom_vinum.c#11 (text+ko) ====
@@ -116,7 +116,7 @@
mtx_unlock(&sc->queue_mtx);
}
-static int
+int
gv_access(struct g_provider *pp, int dr, int dw, int de)
{
struct g_geom *gp;
==== //depot/projects/soc2007/lulf/gvinum_fixup/sys/geom/vinum/geom_vinum.h#9 (text+ko) ====
@@ -96,6 +96,7 @@
void gv_drive_lost(struct gv_softc *, struct gv_drive *);
void gv_setup_objects(struct gv_softc *);
void gv_start(struct bio *);
+int gv_access(struct g_provider *, int, int, int);
void gv_done(struct bio *);
void gv_volume_start(struct gv_softc *, struct bio *);
==== //depot/projects/soc2007/lulf/gvinum_fixup/sys/geom/vinum/geom_vinum_plex.c#6 (text+ko) ====
@@ -367,11 +367,12 @@
pbp->bio_inbed++;
if (pbp->bio_inbed == pbp->bio_children) {
+ printf("Error is %d\n", pbp->bio_error);
/* XXX: Should this be done here? Probably to be done later, but
* just for testing. */
- if (pbp->bio_cmd == BIO_WRITE && (pbp->bio_cflags & GV_BIO_PARITY)) {
+ if (pbp->bio_cmd == BIO_WRITE &&
+ (pbp->bio_cflags & GV_BIO_CHECK)) {
/* Schedule a new bio down to rebuild parity. */
- printf("Finished with rebuild at %lld\n", p->synced);
gv_parity_completed(p, pbp);
} else
g_io_deliver(pbp, pbp->bio_error);
@@ -477,20 +478,30 @@
gv_issue_next_parity_bio(struct gv_plex *p, int rebuild)
{
struct bio *bp;
+ int error;
KASSERT(p != NULL, ("gv_issue_next_parity_bio: NULL p"));
+ g_topology_lock();
+ error = gv_access(p->vol_sc->provider, 1, 1, 0);
+ if (error) {
+ printf("VINUM: unable to access provider\n");
+ goto bad;
+ }
bp = g_new_bio();
if (bp == NULL) {
printf("VINUM: rebuild of %s failed creating bio: "
"out of memory\n", p->name);
- return;
+ gv_access(p->vol_sc->provider, -1, -1, 0);
+ goto bad;
}
+ g_topology_unlock();
bp->bio_cmd = BIO_WRITE;
bp->bio_done = NULL;
bp->bio_data = g_malloc(p->stripesize, M_WAITOK | M_ZERO);
+ bp->bio_error = 0;
/* bp->bio_cflags |= GV_BIO_REBUILD;*/
bp->bio_cflags |= GV_BIO_CHECK;
if (rebuild)
@@ -498,22 +509,16 @@
bp->bio_cflags |= GV_BIO_MALLOC;
bp->bio_length = p->stripesize;
- if (p->synced >= p->size) {
- /* We're finished. */
- printf("VINUM: rebuild of %s finished\n", p->name);
- g_free(bp->bio_data);
- g_destroy_bio(bp);
- p->synced = 0;
- return;
- }
-
/* We still have more parity to build. */
bp->bio_offset = p->synced;
/* Now we need to find the correct subdisk to send it to. */
- p->synced += p->stripesize;
- printf("VINUM: Issuing bio with offset %lld\n", bp->bio_offset);
+ printf("VINUM: Issuing bio at offset 0x%jx\n",
+ (intmax_t)bp->bio_offset);
gv_plex_start(p, bp); /* Send it down to the plex. */
+ return;
+bad:
+ g_topology_unlock();
}
/*
@@ -530,14 +535,33 @@
g_free(bp->bio_data);
g_destroy_bio(bp);
+ g_topology_lock();
+ gv_access(p->vol_sc->provider, -1, -1, 0);
+ g_topology_unlock();
/* Clean up what we allocated. */
/* XXX: Check for error type. */
if (error) {
- printf("VINUM: Parity operation error on %s at %lld\n", p->name,
- p->synced);
+ if (error == EAGAIN) {
+ printf("VINUM: Parity incorrect at offset 0x%jx\n",
+ (intmax_t)p->synced);
+ if (!rebuild)
+ return;
+ }
+ printf("VINUM: Parity check on %s failed at 0x%jx errno %d\n",
+ p->name, (intmax_t)p->synced, error);
+ } else {
+ p->synced += p->stripesize;
+ }
+ printf("VINUM: Parity operation at 0x%jx finished\n",
+ (intmax_t)p->synced);
+
+
+ if (p->synced >= p->size) {
+ /* We're finished. */
+ printf("VINUM: Parity operation on %s finished\n", p->name);
+ p->synced = 0;
return;
}
- printf("VINUM: Parity operation at %lld finished\n", p->synced);
/* Send down next. It will determine if we need to itself. */
gv_issue_next_parity_bio(p, rebuild);
More information about the p4-projects
mailing list