svn commit: r217287 - projects/graid/head/sys/geom/raid

Warner Losh imp at FreeBSD.org
Tue Jan 11 21:43:35 UTC 2011


Author: imp
Date: Tue Jan 11 21:43:35 2011
New Revision: 217287
URL: http://svn.freebsd.org/changeset/base/217287

Log:
  Fix a few problems with read error recovery:
  o We need to check the bp we're given in *done() not pbp since that's where the
    error is.
  o Just check bio_error and forget the BIO_ERROR flag.
  o bump the inbed count a little later in the processing.
  o Start to do write-remapping, but only detect when we need to, rather than
    actually doing anything (yet).
  o minor style cleanup
  o improve mirror breaking/degrading notes and add one.
  
  With these changes I can survive at a 10% error rate both raw
  operations, as well as file system operations...

Modified:
  projects/graid/head/sys/geom/raid/tr_raid1.c

Modified: projects/graid/head/sys/geom/raid/tr_raid1.c
==============================================================================
--- projects/graid/head/sys/geom/raid/tr_raid1.c	Tue Jan 11 21:18:29 2011	(r217286)
+++ projects/graid/head/sys/geom/raid/tr_raid1.c	Tue Jan 11 21:43:35 2011	(r217287)
@@ -291,21 +291,18 @@ static void
 g_raid_tr_iodone_raid1(struct g_raid_tr_object *tr,
     struct g_raid_subdisk *sd, struct bio *bp)
 {
+	struct bio *cbp;
+	struct g_raid_subdisk *nsd;
+	struct g_raid_volume *vol;
 	struct bio *pbp;
+	int i;
 
 	pbp = bp->bio_parent;
-	pbp->bio_inbed++;
-	if ((pbp->bio_flags & BIO_ERROR) && pbp->bio_cmd == BIO_READ &&
+	if (bp->bio_error != 0 && bp->bio_cmd == BIO_READ &&
 	    pbp->bio_children == 1) {
-		struct bio *cbp;
-		struct g_raid_subdisk *nsd;
-		struct g_raid_volume *vol;
-		int i;
-
 		/*
-		 * Retry the error on the other disk drive, if available,
-		 * before erroring out the read.  Do we need to mark the
-		 * 'sd' disk as degraded somehow?
+		 * Retry the read error on the other disk drive, if
+		 * available, before erroring out the read.
 		 */
 		vol = tr->tro_volume;
 		sd->sd_read_errs++;
@@ -323,25 +320,31 @@ g_raid_tr_iodone_raid1(struct g_raid_tr_
 			if (cbp == NULL)
 				break;
 			g_raid_subdisk_iostart(nsd, cbp);
+			pbp->bio_inbed++;
 			return;
 		}
 		/*
 		 * something happened, so we can't retry.  Return the
 		 * original error by falling through.
+		 *
+		 * XXX degrade/break the mirror?
+		 */
+	}
+	pbp->bio_inbed++;
+	if (pbp->bio_cmd == BIO_READ && pbp->bio_children == 2) {
+		/*
+		 * If it was a read, and bio_children is 2, then we just
+		 * recovered the data from the second drive.  We should try to
+		 * write that data to the first drive if sector remapping is
+		 * enabled.  A write should put the data in a new place on the
+		 * disk, remapping the bad sector.  Do we need to do that by
+		 * queueing a request to the main worker thread?  It doesn't
+		 * affect the return code of this current read, and can be
+		 * done at our liesure.
+		 *
+		 * XXX TODO
 		 */
 	}
-	/*
-	 * If it was a read, and bio_children is 2, then we just
-	 * recovered the data from the second drive.  We should try to
-	 * write that data to the first drive if sector remapping is
-	 * enabled.  A write should put the data in a new place on the
-	 * disk, remapping the bad sector.  Do we need to do that by
-	 * queueing a request to the main worker thread?  It doesn't
-	 * affect the return code of this current read, and can be
-	 * done at our liesure.
-	 *
-	 * XXX TODO
-	 */
 	if (pbp->bio_children == pbp->bio_inbed) {
 		pbp->bio_completed = pbp->bio_length;
 		g_raid_iodone(pbp, bp->bio_error);


More information about the svn-src-projects mailing list