9954 loader: always set media size from partition.
Reviewed by: C Fraire <cfraire@me.com>
Reviewed by: Andy Fiddaman <andy@omniosce.org>
Approved by: Dan McDonald <danmcd@joyent.com>
diff --git a/usr/src/boot/sys/boot/common/disk.c b/usr/src/boot/sys/boot/common/disk.c
index 2b89274..7d48e28 100644
--- a/usr/src/boot/sys/boot/common/disk.c
+++ b/usr/src/boot/sys/boot/common/disk.c
@@ -262,9 +262,7 @@
 		rc = ENXIO;
 		goto out;
 	}
-	if (mediasize > od->mediasize) {
-		od->mediasize = mediasize;
-	}
+	od->mediasize = mediasize;
 
 	if (ptable_gettype(od->table) == PTABLE_BSD &&
 	    partition >= 0) {
diff --git a/usr/src/boot/sys/boot/common/part.c b/usr/src/boot/sys/boot/common/part.c
index 1e3d8bf..25a9cf9 100644
--- a/usr/src/boot/sys/boot/common/part.c
+++ b/usr/src/boot/sys/boot/common/part.c
@@ -342,8 +342,7 @@
 	 * Note, this is still not a foolproof way to get disk's size. For
 	 * example, an image file can be truncated when copied to smaller media.
 	 */
-	if (hdr.hdr_lba_alt + 1 > table->sectors)
-		table->sectors = hdr.hdr_lba_alt + 1;
+	table->sectors = hdr.hdr_lba_alt + 1;
 
 	for (i = 0; i < size / hdr.hdr_entsz; i++) {
 		ent = (struct gpt_ent *)(tbl + i * hdr.hdr_entsz);
diff --git a/usr/src/boot/sys/boot/i386/libi386/biosdisk.c b/usr/src/boot/sys/boot/i386/libi386/biosdisk.c
index 3db2144..30af54e 100644
--- a/usr/src/boot/sys/boot/i386/libi386/biosdisk.c
+++ b/usr/src/boot/sys/boot/i386/libi386/biosdisk.c
@@ -440,6 +440,33 @@
 }
 
 /*
+ * Read disk size from partition.
+ * This is needed to work around buggy BIOS systems returning
+ * wrong (truncated) disk media size.
+ * During bd_probe() we tested if the multiplication of bd_sectors
+ * would overflow so it should be safe to perform here.
+ */
+static uint64_t
+bd_disk_get_sectors(struct disk_devdesc *dev)
+{
+	struct disk_devdesc disk;
+	uint64_t size;
+
+	disk.dd.d_dev = dev->dd.d_dev;
+	disk.dd.d_unit = dev->dd.d_unit;
+	disk.d_slice = -1;
+	disk.d_partition = -1;
+	disk.d_offset = 0;
+
+	size = BD(dev).bd_sectors * BD(dev).bd_sectorsize;
+	if (disk_open(&disk, size, BD(dev).bd_sectorsize) == 0) {
+		(void) disk_ioctl(&disk, DIOCGMEDIASIZE, &size);
+		disk_close(&disk);
+	}
+	return (size / BD(dev).bd_sectorsize);
+}
+
+/*
  * Attempt to open the disk described by (dev) for use by (f).
  *
  * Note that the philosophy here is "give them exactly what
@@ -453,9 +480,7 @@
 bd_open(struct open_file *f, ...)
 {
 	struct disk_devdesc *dev;
-	struct disk_devdesc disk;
 	va_list ap;
-	uint64_t size;
 	int rc;
 
 	va_start(ap, f);
@@ -471,33 +496,12 @@
 		if ((BD(dev).bd_flags & BD_NO_MEDIA) == BD_NO_MEDIA)
 			return (EIO);
 	}
-	BD(dev).bd_open++;
 	if (BD(dev).bd_bcache == NULL)
 	    BD(dev).bd_bcache = bcache_allocate();
 
-	/*
-	 * Read disk size from partition.
-	 * This is needed to work around buggy BIOS systems returning
-	 * wrong (truncated) disk media size.
-	 * During bd_probe() we tested if the mulitplication of bd_sectors
-	 * would overflow so it should be safe to perform here.
-	 */
-	disk.dd.d_dev = dev->dd.d_dev;
-	disk.dd.d_unit = dev->dd.d_unit;
-	disk.d_slice = -1;
-	disk.d_partition = -1;
-	disk.d_offset = 0;
-
-	if (disk_open(&disk, BD(dev).bd_sectors * BD(dev).bd_sectorsize,
-	    BD(dev).bd_sectorsize) == 0) {
-
-		if (disk_ioctl(&disk, DIOCGMEDIASIZE, &size) == 0) {
-			size /= BD(dev).bd_sectorsize;
-			if (size > BD(dev).bd_sectors)
-				BD(dev).bd_sectors = size;
-		}
-		disk_close(&disk);
-	}
+	if (BD(dev).bd_open == 0)
+		BD(dev).bd_sectors = bd_disk_get_sectors(dev);
+	BD(dev).bd_open++;
 
 	rc = disk_open(dev, BD(dev).bd_sectors * BD(dev).bd_sectorsize,
 	    BD(dev).bd_sectorsize);