Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F150993262
D8595.id22420.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
2 KB
Referenced Files
None
Subscribers
None
D8595.id22420.diff
View Options
Index: sys/boot/i386/libi386/biosdisk.c
===================================================================
--- sys/boot/i386/libi386/biosdisk.c
+++ sys/boot/i386/libi386/biosdisk.c
@@ -377,6 +377,7 @@
bd_open(struct open_file *f, ...)
{
struct disk_devdesc *dev, rdev;
+ struct disk_devdesc disk;
int err, g_err;
va_list ap;
@@ -389,6 +390,32 @@
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.
+ */
+ disk.d_dev = dev->d_dev;
+ disk.d_type = dev->d_type;
+ disk.d_unit = dev->d_unit;
+ disk.d_opendata = NULL;
+ 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, (BD(dev).bd_flags & BD_FLOPPY) ?
+ DISK_F_NOCACHE: 0) == 0) {
+ off_t size;
+
+ 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);
+ }
+
err = disk_open(dev, BD(dev).bd_sectors * BD(dev).bd_sectorsize,
BD(dev).bd_sectorsize, (BD(dev).bd_flags & BD_FLOPPY) ?
DISK_F_NOCACHE: 0);
@@ -486,8 +513,14 @@
bd_ioctl(struct open_file *f, u_long cmd, void *data)
{
struct disk_devdesc *dev;
+ int rc;
dev = (struct disk_devdesc *)f->f_devdata;
+
+ rc = disk_ioctl(dev, cmd, data);
+ if (rc != ENOTTY)
+ return (rc);
+
switch (cmd) {
case DIOCGSECTORSIZE:
*(u_int *)data = BD(dev).bd_sectorsize;
@@ -521,7 +554,8 @@
char *buf, size_t *rsize)
{
struct disk_devdesc *dev = (struct disk_devdesc *)devdata;
- int blks, remaining;
+ off_t disk_blocks;
+ int blks;
#ifdef BD_SUPPORT_FRAGS /* XXX: sector size */
char fragbuf[BIOSDISK_SECSIZE];
size_t fragsize;
@@ -537,15 +571,20 @@
if (rsize)
*rsize = 0;
+ /* Get disk blocks, this value is either for whole disk or for partition */
+ if (disk_ioctl(dev, DIOCGMEDIASIZE, &disk_blocks))
+ disk_blocks = BD(dev).bd_sectors;
+ disk_blocks /= BD(dev).bd_sectorsize;
+
+ /* IO past disk or partition size */
+ if (dblk >= dev->d_offset + disk_blocks)
+ return (EIO);
+
/*
- * Perform partial read to prevent read-ahead crossing
- * the end of disk - or any 32 bit aliases of the end.
- * Signed arithmetic is used to handle wrap-around cases
- * like we do for TCP sequence numbers.
+ * Truncate if we are crossing disk or partition end.
*/
- remaining = (int)(BD(dev).bd_sectors - dblk); /* truncate */
- if (remaining > 0 && remaining < blks) {
- blks = remaining;
+ if (dblk + blks >= dev->d_offset + disk_blocks) {
+ blks = dev->d_offset + disk_blocks - dblk;
size = blks * BD(dev).bd_sectorsize;
DEBUG("short read %d", blks);
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Apr 6, 8:45 AM (11 h, 20 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
30952576
Default Alt Text
D8595.id22420.diff (2 KB)
Attached To
Mode
D8595: loader biosdisk fix for 2+TB disks.
Attached
Detach File
Event Timeline
Log In to Comment