Fix efi_use_whole_disk() when efi_nparts == 128.
Commit e5dc681a
changed EFI_NUMPAR from 9 to 128. This means that the
on-disk EFI label has efi_nparts = 128 instead of 9. The index of the
reserved partition, however, is still 8. This breaks
efi_use_whole_disk(), which uses efi_nparts-1 as the index of the
reserved partition.
This commit fixes efi_use_whole_disk() when the index of the reserved
partition is not efi_nparts-1. It rewrites the algorithm and makes it
more robust by using the order of the partitions instead of their
numbering. It assumes that the last non-empty partition is the reserved
partition, and that the non-empty partition before that is the data
partition.
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Issue #808
This commit is contained in:
parent
7608bd0dd0
commit
cee43a7477
|
@ -1028,24 +1028,15 @@ efi_use_whole_disk(int fd)
|
||||||
struct dk_gpt *efi_label;
|
struct dk_gpt *efi_label;
|
||||||
int rval;
|
int rval;
|
||||||
int i;
|
int i;
|
||||||
uint_t phy_last_slice = 0;
|
uint_t resv_index = 0, data_index = 0;
|
||||||
diskaddr_t pl_start = 0;
|
diskaddr_t resv_start = 0, data_start = 0;
|
||||||
diskaddr_t pl_size;
|
diskaddr_t difference;
|
||||||
|
|
||||||
rval = efi_alloc_and_read(fd, &efi_label);
|
rval = efi_alloc_and_read(fd, &efi_label);
|
||||||
if (rval < 0) {
|
if (rval < 0) {
|
||||||
return (rval);
|
return (rval);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* find the last physically non-zero partition */
|
|
||||||
for (i = 0; i < efi_label->efi_nparts - 2; i ++) {
|
|
||||||
if (pl_start < efi_label->efi_parts[i].p_start) {
|
|
||||||
pl_start = efi_label->efi_parts[i].p_start;
|
|
||||||
phy_last_slice = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pl_size = efi_label->efi_parts[phy_last_slice].p_size;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If alter_lba is 1, we are using the backup label.
|
* If alter_lba is 1, we are using the backup label.
|
||||||
* Since we can locate the backup label by disk capacity,
|
* Since we can locate the backup label by disk capacity,
|
||||||
|
@ -1061,16 +1052,28 @@ efi_use_whole_disk(int fd)
|
||||||
return (VT_ENOSPC);
|
return (VT_ENOSPC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
difference = efi_label->efi_last_lba - efi_label->efi_altern_lba;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If there is space between the last physically non-zero partition
|
* Find the last physically non-zero partition.
|
||||||
* and the reserved partition, just add the unallocated space to this
|
* This is the reserved partition.
|
||||||
* area. Otherwise, the unallocated space is added to the last
|
|
||||||
* physically non-zero partition.
|
|
||||||
*/
|
*/
|
||||||
if (pl_start + pl_size - 1 == efi_label->efi_last_u_lba -
|
for (i = 0; i < efi_label->efi_nparts; i ++) {
|
||||||
EFI_MIN_RESV_SIZE) {
|
if (resv_start < efi_label->efi_parts[i].p_start) {
|
||||||
efi_label->efi_parts[phy_last_slice].p_size +=
|
resv_start = efi_label->efi_parts[i].p_start;
|
||||||
efi_label->efi_last_lba - efi_label->efi_altern_lba;
|
resv_index = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find the last physically non-zero partition before that.
|
||||||
|
* This is the data partition.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < resv_index; i ++) {
|
||||||
|
if (data_start < efi_label->efi_parts[i].p_start) {
|
||||||
|
data_start = efi_label->efi_parts[i].p_start;
|
||||||
|
data_index = i;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1078,10 +1081,9 @@ efi_use_whole_disk(int fd)
|
||||||
* here except fabricated devids (which get generated via
|
* here except fabricated devids (which get generated via
|
||||||
* efi_write()). So there is no need to copy data.
|
* efi_write()). So there is no need to copy data.
|
||||||
*/
|
*/
|
||||||
efi_label->efi_parts[efi_label->efi_nparts - 1].p_start +=
|
efi_label->efi_parts[data_index].p_size += difference;
|
||||||
efi_label->efi_last_lba - efi_label->efi_altern_lba;
|
efi_label->efi_parts[resv_index].p_start += difference;
|
||||||
efi_label->efi_last_u_lba += efi_label->efi_last_lba
|
efi_label->efi_last_u_lba += difference;
|
||||||
- efi_label->efi_altern_lba;
|
|
||||||
|
|
||||||
rval = efi_write(fd, efi_label);
|
rval = efi_write(fd, efi_label);
|
||||||
if (rval < 0) {
|
if (rval < 0) {
|
||||||
|
|
Loading…
Reference in New Issue