Date: Wed, 7 Nov 2018 11:14:22 +0000 (UTC) From: Toomas Soome <tsoome@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r340215 - in head/stand: common i386/libi386 Message-ID: <201811071114.wA7BEMSf023293@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201811071114.wA7BEMSf023293>