changeset 9917:4de88cdeac3d

6836480 PV Fedora10 fails to boot on xdb backend
author Mark Johnson <Mark.Johnson@Sun.COM>
date Fri, 19 Jun 2009 17:22:46 -0700
parents 1b3679ce7b31
children dd75fc2aa755
files usr/src/uts/common/xen/io/xdb.c usr/src/uts/common/xen/io/xdf.h
diffstat 2 files changed, 31 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/uts/common/xen/io/xdb.c	Fri Jun 19 11:57:00 2009 -0700
+++ b/usr/src/uts/common/xen/io/xdb.c	Fri Jun 19 17:22:46 2009 -0700
@@ -299,13 +299,13 @@
 			/*
 			 * first_sect should be no bigger than last_sect and
 			 * both of them should be no bigger than
-			 * (PAGESIZE / XB_BSIZE - 1) according to definition
+			 * XB_LAST_SECTOR_IN_SEG according to definition
 			 * of blk interface by Xen, so sanity check again
 			 */
-			if (fs > (PAGESIZE / XB_BSIZE - 1))
-				fs = PAGESIZE / XB_BSIZE - 1;
-			if (ls > (PAGESIZE / XB_BSIZE - 1))
-				ls = PAGESIZE / XB_BSIZE - 1;
+			if (fs > XB_LAST_SECTOR_IN_SEG)
+				fs = XB_LAST_SECTOR_IN_SEG;
+			if (ls > XB_LAST_SECTOR_IN_SEG)
+				ls = XB_LAST_SECTOR_IN_SEG;
 			if (fs > ls)
 				fs = ls;
 
@@ -406,15 +406,31 @@
 	bp->b_shadow = &xreq->xr_pplist[curseg];
 	bp->b_iodone = xdb_biodone;
 	sectors = 0;
+
+	/*
+	 * Run through the segments. There are XB_NUM_SECTORS_PER_SEG sectors
+	 * per segment. On some OSes (e.g. Linux), there may be empty gaps
+	 * between segments. (i.e. the first segment may end on sector 6 and
+	 * the second segment start on sector 4).
+	 *
+	 * if a segments first sector is not set to 0, and this is not the
+	 * first segment in our buf, end this buf now.
+	 *
+	 * if a segments last sector is not set to XB_LAST_SECTOR_IN_SEG, and
+	 * this is not the last segment in the request, add this segment into
+	 * the buf, then end this buf (updating the pointer to point to the
+	 * next segment next time around).
+	 */
 	for (i = curseg; i < xreq->xr_buf_pages; i++) {
-		/*
-		 * The xreq->xr_segs[i].fs of the first seg can be non-zero
-		 * otherwise, we'll break it into multiple bufs
-		 */
-		if ((i != curseg) && (xreq->xr_segs[i].fs != 0)) {
+		if ((xreq->xr_segs[i].fs != 0) && (i != curseg)) {
 			break;
 		}
 		sectors += (xreq->xr_segs[i].ls - xreq->xr_segs[i].fs + 1);
+		if ((xreq->xr_segs[i].ls != XB_LAST_SECTOR_IN_SEG) &&
+		    (i != (xreq->xr_buf_pages - 1))) {
+			i++;
+			break;
+		}
 	}
 	xreq->xr_curseg = i;
 	bp->b_bcount = sectors * DEV_BSIZE;
--- a/usr/src/uts/common/xen/io/xdf.h	Fri Jun 19 11:57:00 2009 -0700
+++ b/usr/src/uts/common/xen/io/xdf.h	Fri Jun 19 17:22:46 2009 -0700
@@ -55,6 +55,11 @@
 #define	XB_MAX_XFER	(XB_MAX_SEGLEN * BLKIF_MAX_SEGMENTS_PER_REQUEST)
 #define	XB_MAXPHYS	(XB_MAX_XFER * BLKIF_RING_SIZE)
 
+/* Number of sectors per segement */
+#define	XB_NUM_SECTORS_PER_SEG	(PAGESIZE / XB_BSIZE)
+/* sectors are number 0 through XB_NUM_SECTORS_PER_SEG - 1 */
+#define	XB_LAST_SECTOR_IN_SEG	(XB_NUM_SECTORS_PER_SEG - 1)
+
 
 /*
  * Slice for absolute disk transaction.