Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 25 Oct 2014 15:16:20 +0000 (UTC)
From:      Alexander Motin <mav@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r273638 - in head/sys: geom kern
Message-ID:  <201410251516.s9PFGKuN059261@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mav
Date: Sat Oct 25 15:16:19 2014
New Revision: 273638
URL: https://svnweb.freebsd.org/changeset/base/273638

Log:
  Revert somewhat hackish geom_disk optimization, committed as part of r256880,
  and the following r273143 commit, supposed to workaround introduced issue by
  quite innocent-looking change.
  
  While there is no clear understanding why, but r273143 is accused in data
  corruption in some environments with high I/O load.  I personally don't see
  any problem in that commit, and possibly it is just a trigger to some other
  bug somewhere, but better safe then sorry for now.
  
  Requested by:	scottl@
  MFC after:	3 days

Modified:
  head/sys/geom/geom_disk.c
  head/sys/kern/vfs_bio.c

Modified: head/sys/geom/geom_disk.c
==============================================================================
--- head/sys/geom/geom_disk.c	Sat Oct 25 15:14:19 2014	(r273637)
+++ head/sys/geom/geom_disk.c	Sat Oct 25 15:16:19 2014	(r273638)
@@ -235,25 +235,6 @@ g_disk_done(struct bio *bp)
 	g_destroy_bio(bp);
 }
 
-static void
-g_disk_done_single(struct bio *bp)
-{
-	struct bintime now;
-	struct g_disk_softc *sc;
-
-	bp->bio_completed = bp->bio_length - bp->bio_resid;
-	bp->bio_done = (void *)bp->bio_to;
-	bp->bio_to = LIST_FIRST(&bp->bio_disk->d_geom->provider);
-	if ((bp->bio_cmd & (BIO_READ|BIO_WRITE|BIO_DELETE|BIO_FLUSH)) != 0) {
-		binuptime(&now);
-		sc = bp->bio_to->private;
-		mtx_lock(&sc->done_mtx);
-		devstat_end_transaction_bio_bt(sc->dp->d_devstat, bp, &now);
-		mtx_unlock(&sc->done_mtx);
-	}
-	g_io_deliver(bp, bp->bio_error);
-}
-
 static int
 g_disk_ioctl(struct g_provider *pp, u_long cmd, void * data, int fflag, struct thread *td)
 {
@@ -277,7 +258,7 @@ g_disk_start(struct bio *bp)
 	struct disk *dp;
 	struct g_disk_softc *sc;
 	int error;
-	off_t d_maxsize, off;
+	off_t off;
 
 	sc = bp->bio_to->private;
 	if (sc == NULL || (dp = sc->dp) == NULL || dp->d_destroyed) {
@@ -294,20 +275,6 @@ g_disk_start(struct bio *bp)
 		/* fall-through */
 	case BIO_READ:
 	case BIO_WRITE:
-		d_maxsize = (bp->bio_cmd == BIO_DELETE) ?
-		    dp->d_delmaxsize : dp->d_maxsize;
-		if (bp->bio_length <= d_maxsize) {
-			bp->bio_disk = dp;
-			bp->bio_to = (void *)bp->bio_done;
-			bp->bio_done = g_disk_done_single;
-			bp->bio_pblkno = bp->bio_offset / dp->d_sectorsize;
-			bp->bio_bcount = bp->bio_length;
-			mtx_lock(&sc->start_mtx);
-			devstat_start_transaction_bio(dp->d_devstat, bp);
-			mtx_unlock(&sc->start_mtx);
-			dp->d_strategy(bp);
-			break;
-		}
 		off = 0;
 		bp3 = NULL;
 		bp2 = g_clone_bio(bp);
@@ -316,6 +283,10 @@ g_disk_start(struct bio *bp)
 			break;
 		}
 		do {
+			off_t d_maxsize;
+
+			d_maxsize = (bp->bio_cmd == BIO_DELETE) ?
+			    dp->d_delmaxsize : dp->d_maxsize;
 			bp2->bio_offset += off;
 			bp2->bio_length -= off;
 			if ((bp->bio_flags & BIO_UNMAPPED) == 0) {
@@ -415,13 +386,17 @@ g_disk_start(struct bio *bp)
 			error = EOPNOTSUPP;
 			break;
 		}
-		bp->bio_disk = dp;
-		bp->bio_to = (void *)bp->bio_done;
-		bp->bio_done = g_disk_done_single;
-		mtx_lock(&sc->start_mtx); 
-		devstat_start_transaction_bio(dp->d_devstat, bp);
-		mtx_unlock(&sc->start_mtx); 
-		dp->d_strategy(bp);
+		bp2 = g_clone_bio(bp);
+		if (bp2 == NULL) {
+			g_io_deliver(bp, ENOMEM);
+			return;
+		}
+		bp2->bio_done = g_disk_done;
+		bp2->bio_disk = dp;
+		mtx_lock(&sc->start_mtx);
+		devstat_start_transaction_bio(dp->d_devstat, bp2);
+		mtx_unlock(&sc->start_mtx);
+		dp->d_strategy(bp2);
 		break;
 	default:
 		error = EOPNOTSUPP;

Modified: head/sys/kern/vfs_bio.c
==============================================================================
--- head/sys/kern/vfs_bio.c	Sat Oct 25 15:14:19 2014	(r273637)
+++ head/sys/kern/vfs_bio.c	Sat Oct 25 15:16:19 2014	(r273638)
@@ -3618,8 +3618,10 @@ biodone(struct bio *bp)
 		bp->bio_flags |= BIO_DONE;
 		wakeup(bp);
 		mtx_unlock(mtxp);
-	} else
+	} else {
+		bp->bio_flags |= BIO_DONE;
 		done(bp);
+	}
 }
 
 /*



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201410251516.s9PFGKuN059261>