efi_loader: correct EFI_BLOCK_IO_PROTOCOL.Media.LastBlock
The field Media.LastBlock of the EFI_BLOCK_IO_PROTOCOL.Media was filled incorrectly both for block devices as well as for partitions. The field must be filled with the index of the last logical block (LBA): * block devices: device size minus 1 * partitions: partition size minus 1 Reported-by: Alexander von Gluck IV <kallisti5@unixzen.com> Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
This commit is contained in:
parent
2cfb68fd83
commit
8d0949b3ed
@ -343,7 +343,7 @@ static int efi_fs_exists(struct blk_desc *desc, int part)
|
||||
* @if_typename: interface name for block device
|
||||
* @desc: internal block device
|
||||
* @dev_index: device index for block device
|
||||
* @offset: offset into disk for simple partitions
|
||||
* @part_info: partition info
|
||||
* @part: partition
|
||||
* @disk: pointer to receive the created handle
|
||||
* Return: disk object
|
||||
@ -354,7 +354,7 @@ static efi_status_t efi_disk_add_dev(
|
||||
const char *if_typename,
|
||||
struct blk_desc *desc,
|
||||
int dev_index,
|
||||
lbaint_t offset,
|
||||
struct disk_partition *part_info,
|
||||
unsigned int part,
|
||||
struct efi_disk_obj **disk)
|
||||
{
|
||||
@ -374,7 +374,7 @@ static efi_status_t efi_disk_add_dev(
|
||||
efi_add_handle(&diskobj->header);
|
||||
|
||||
/* Fill in object data */
|
||||
if (part) {
|
||||
if (part_info) {
|
||||
struct efi_device_path *node = efi_dp_part_node(desc, part);
|
||||
struct efi_handler *handler;
|
||||
void *protocol_interface;
|
||||
@ -396,8 +396,12 @@ static efi_status_t efi_disk_add_dev(
|
||||
|
||||
diskobj->dp = efi_dp_append_node(dp_parent, node);
|
||||
efi_free_pool(node);
|
||||
diskobj->offset = part_info->start;
|
||||
diskobj->media.last_block = part_info->size - 1;
|
||||
} else {
|
||||
diskobj->dp = efi_dp_from_part(desc, part);
|
||||
diskobj->offset = 0;
|
||||
diskobj->media.last_block = desc->lba - 1;
|
||||
}
|
||||
diskobj->part = part;
|
||||
|
||||
@ -432,7 +436,6 @@ static efi_status_t efi_disk_add_dev(
|
||||
diskobj->ops = block_io_disk_template;
|
||||
diskobj->ifname = if_typename;
|
||||
diskobj->dev_index = dev_index;
|
||||
diskobj->offset = offset;
|
||||
diskobj->desc = desc;
|
||||
|
||||
/* Fill in EFI IO Media info (for read/write callbacks) */
|
||||
@ -445,13 +448,21 @@ static efi_status_t efi_disk_add_dev(
|
||||
diskobj->media.media_id = 1;
|
||||
diskobj->media.block_size = desc->blksz;
|
||||
diskobj->media.io_align = desc->blksz;
|
||||
diskobj->media.last_block = desc->lba - offset;
|
||||
if (part)
|
||||
diskobj->media.logical_partition = 1;
|
||||
diskobj->ops.media = &diskobj->media;
|
||||
if (disk)
|
||||
*disk = diskobj;
|
||||
|
||||
EFI_PRINT("BlockIO: part %u, present %d, logical %d, removable %d"
|
||||
", offset " LBAF ", last_block %llu\n",
|
||||
diskobj->part,
|
||||
diskobj->media.media_present,
|
||||
diskobj->media.logical_partition,
|
||||
diskobj->media.removable_media,
|
||||
diskobj->offset,
|
||||
diskobj->media.last_block);
|
||||
|
||||
/* Store first EFI system partition */
|
||||
if (part && !efi_system_partition.if_type) {
|
||||
int r;
|
||||
@ -493,7 +504,6 @@ int efi_disk_create_partitions(efi_handle_t parent, struct blk_desc *desc,
|
||||
{
|
||||
int disks = 0;
|
||||
char devname[32] = { 0 }; /* dp->str is u16[32] long */
|
||||
struct disk_partition info;
|
||||
int part;
|
||||
struct efi_device_path *dp = NULL;
|
||||
efi_status_t ret;
|
||||
@ -506,12 +516,14 @@ int efi_disk_create_partitions(efi_handle_t parent, struct blk_desc *desc,
|
||||
|
||||
/* Add devices for each partition */
|
||||
for (part = 1; part <= MAX_SEARCH_PARTITIONS; part++) {
|
||||
struct disk_partition info;
|
||||
|
||||
if (part_get_info(desc, part, &info))
|
||||
continue;
|
||||
snprintf(devname, sizeof(devname), "%s:%d", pdevname,
|
||||
part);
|
||||
ret = efi_disk_add_dev(parent, dp, if_typename, desc, diskid,
|
||||
info.start, part, NULL);
|
||||
&info, part, NULL);
|
||||
if (ret != EFI_SUCCESS) {
|
||||
log_err("Adding partition %s failed\n", pdevname);
|
||||
continue;
|
||||
@ -553,7 +565,7 @@ efi_status_t efi_disk_register(void)
|
||||
/* Add block device for the full device */
|
||||
log_info("Scanning disk %s...\n", dev->name);
|
||||
ret = efi_disk_add_dev(NULL, NULL, if_typename,
|
||||
desc, desc->devnum, 0, 0, &disk);
|
||||
desc, desc->devnum, NULL, 0, &disk);
|
||||
if (ret == EFI_NOT_READY) {
|
||||
log_notice("Disk %s not ready\n", dev->name);
|
||||
continue;
|
||||
@ -599,7 +611,7 @@ efi_status_t efi_disk_register(void)
|
||||
|
||||
/* Add block device for the full device */
|
||||
ret = efi_disk_add_dev(NULL, NULL, if_typename, desc,
|
||||
i, 0, 0, &disk);
|
||||
i, NULL, 0, &disk);
|
||||
if (ret == EFI_NOT_READY) {
|
||||
log_notice("Disk %s not ready\n", devname);
|
||||
continue;
|
||||
|
Loading…
Reference in New Issue
Block a user