Author: tsoome
Date: Wed Nov  7 11:14:22 2018
New Revision: 340215
URL: https://svnweb.freebsd.org/changeset/base/340215

Log:
  loader: always set media size from partition.
  
  The disk access is validated by using partition table definitions, therefore
  we have no need for if statements, just set the disk size.
  
  Of course the partition table itself may be incorrect/inconsistent, but if
  so, we are in trouble anyhow.
  
  Differential Revision:        https://reviews.freebsd.org/D17822

Modified:
  head/stand/common/disk.c
  head/stand/common/part.c
  head/stand/i386/libi386/biosdisk.c

Modified: head/stand/common/disk.c
==============================================================================
--- head/stand/common/disk.c    Wed Nov  7 09:55:31 2018        (r340214)
+++ head/stand/common/disk.c    Wed Nov  7 11:14:22 2018        (r340215)
@@ -265,9 +265,7 @@ disk_open(struct disk_devdesc *dev, uint64_t mediasize
                rc = ENXIO;
                goto out;
        }
-       if (mediasize > od->mediasize) {
-               od->mediasize = mediasize;
-       }
+       od->mediasize = mediasize;
 
        if (ptable_gettype(od->table) == PTABLE_BSD &&
            partition >= 0) {

Modified: head/stand/common/part.c
==============================================================================
--- head/stand/common/part.c    Wed Nov  7 09:55:31 2018        (r340214)
+++ head/stand/common/part.c    Wed Nov  7 11:14:22 2018        (r340215)
@@ -323,8 +323,7 @@ ptable_gptread(struct ptable *table, void *dev, diskre
         * 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);

Modified: head/stand/i386/libi386/biosdisk.c
==============================================================================
--- head/stand/i386/libi386/biosdisk.c  Wed Nov  7 09:55:31 2018        
(r340214)
+++ head/stand/i386/libi386/biosdisk.c  Wed Nov  7 11:14:22 2018        
(r340215)
@@ -439,6 +439,33 @@ bd_print(int verbose)
 }
 
 /*
+ * 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
@@ -452,9 +479,7 @@ static int
 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);
@@ -470,33 +495,12 @@ bd_open(struct open_file *f, ...)
                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);
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to