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
This commit is contained in:
tsoome 2018-11-07 11:14:22 +00:00
parent 573e268cd6
commit d61f54de57
3 changed files with 32 additions and 31 deletions

View File

@ -265,9 +265,7 @@ disk_open(struct disk_devdesc *dev, uint64_t mediasize, u_int sectorsize)
rc = ENXIO;
goto out;
}
if (mediasize > od->mediasize) {
od->mediasize = mediasize;
}
od->mediasize = mediasize;
if (ptable_gettype(od->table) == PTABLE_BSD &&
partition >= 0) {

View File

@ -323,8 +323,7 @@ ptable_gptread(struct ptable *table, void *dev, diskread_t dread)
* 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);

View File

@ -438,6 +438,33 @@ bd_print(int verbose)
return (ret);
}
/*
* 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).
*
@ -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);