staticinlineint pmbr_part_valid(gpt_mbr_record *part)
{ if (part->os_type != EFI_PMBR_OSTYPE_EFI_GPT) goto invalid;
/* set to 0x00000001 (i.e., the LBA of the GPT Partition Header) */ if (le32_to_cpu(part->starting_lba) != GPT_PRIMARY_PARTITION_TABLE_LBA) goto invalid;
return GPT_MBR_PROTECTIVE;
invalid: return0;
}
/** *is_pmbr_valid():testProtectiveMBRforvalidity *@mbr:pointertoalegacymbrstructure *@total_sectors:amountofsectorsinthedevice * *Description:Checksforavalidprotectiveorhybrid *masterbootrecord(MBR).ThevalidityofapMBRdepends *onallofthefollowingproperties: *1)MSDOSsignatureisinthelasttwobytesoftheMBR *2)Onepartitionoftype0xEEisfound * *Inaddition,ahybridMBRwillhaveuptothreeadditional *primarypartitions,whichpointtothesamespacethat's *markedoutbyuptothreeGPTpartitions. * *Returns0uponinvalidMBR,orGPT_MBR_PROTECTIVEor *GPT_MBR_HYBRIDdependingonthedevicelayout.
*/ staticint is_pmbr_valid(legacy_mbr *mbr, sector_t total_sectors)
{
uint32_t sz = 0; int i, part = 0, ret = 0; /* invalid by default */
if (!mbr || le16_to_cpu(mbr->signature) != MSDOS_MBR_SIGNATURE) goto done;
for (i = 0; i < 4; i++) {
ret = pmbr_part_valid(&mbr->partition_record[i]); if (ret == GPT_MBR_PROTECTIVE) {
part = i; /* *Ok,weatleastknowthatthere'saprotectiveMBR, *nowcheckifthereareotherpartitiontypesfor *hybridMBR.
*/ goto check_hybrid;
}
}
if (ret != GPT_MBR_PROTECTIVE) goto done;
check_hybrid: for (i = 0; i < 4; i++) if ((mbr->partition_record[i].os_type !=
EFI_PMBR_OSTYPE_EFI_GPT) &&
(mbr->partition_record[i].os_type != 0x00))
ret = GPT_MBR_HYBRID;
/* *ProtectiveMBRstakeupthelesserofthewholedisk *or2TiB(32bitLBA),ignoringtherestofthedisk. *Somepartitioningprograms,nonetheless,choosetoset *thesizetothemaximum32-bitlimitation,disregarding *thedisksize. * *HybridMBRsdonotnecessarilycomplywiththis. * *Considerabadvalueheretobeawarningtosupportdd'ing *animagefromasmallerdisktoalargerdisk.
*/ if (ret == GPT_MBR_PROTECTIVE) {
sz = le32_to_cpu(mbr->partition_record[part].size_in_lba); if (sz != (uint32_t) total_sectors - 1 && sz != 0xFFFFFFFF)
pr_debug("GPT: mbr size in lba (%u) different than whole disk (%u).\n",
sz, min_t(uint32_t,
total_sectors - 1, 0xFFFFFFFF));
}
done: return ret;
}
if (!ptes) return0; if (!(*gpt = alloc_read_gpt_header(state, lba))) return0;
/* Check the GUID Partition Table signature */ if (le64_to_cpu((*gpt)->signature) != GPT_HEADER_SIGNATURE) {
pr_debug("GUID Partition Table Header signature is wrong:" "%lld != %lld\n",
(unsignedlonglong)le64_to_cpu((*gpt)->signature),
(unsignedlonglong)GPT_HEADER_SIGNATURE); goto fail;
}
/* Check the GUID Partition Table header size is too big */ if (le32_to_cpu((*gpt)->header_size) >
queue_logical_block_size(state->disk->queue)) {
pr_debug("GUID Partition Table Header size is too large: %u > %u\n",
le32_to_cpu((*gpt)->header_size),
queue_logical_block_size(state->disk->queue)); goto fail;
}
/* Check the GUID Partition Table header size is too small */ if (le32_to_cpu((*gpt)->header_size) < sizeof(gpt_header)) {
pr_debug("GUID Partition Table Header size is too small: %u < %zu\n",
le32_to_cpu((*gpt)->header_size), sizeof(gpt_header)); goto fail;
}
/* Check that the my_lba entry points to the LBA that contains
* the GUID Partition Table */ if (le64_to_cpu((*gpt)->my_lba) != lba) {
pr_debug("GPT my_lba incorrect: %lld != %lld\n",
(unsignedlonglong)le64_to_cpu((*gpt)->my_lba),
(unsignedlonglong)lba); goto fail;
}
/* Check the first_usable_lba and last_usable_lba are *withinthedisk.
*/
lastlba = last_lba(state->disk); if (le64_to_cpu((*gpt)->first_usable_lba) > lastlba) {
pr_debug("GPT: first_usable_lba incorrect: %lld > %lld\n",
(unsignedlonglong)le64_to_cpu((*gpt)->first_usable_lba),
(unsignedlonglong)lastlba); goto fail;
} if (le64_to_cpu((*gpt)->last_usable_lba) > lastlba) {
pr_debug("GPT: last_usable_lba incorrect: %lld > %lld\n",
(unsignedlonglong)le64_to_cpu((*gpt)->last_usable_lba),
(unsignedlonglong)lastlba); goto fail;
} if (le64_to_cpu((*gpt)->last_usable_lba) < le64_to_cpu((*gpt)->first_usable_lba)) {
pr_debug("GPT: last_usable_lba incorrect: %lld > %lld\n",
(unsignedlonglong)le64_to_cpu((*gpt)->last_usable_lba),
(unsignedlonglong)le64_to_cpu((*gpt)->first_usable_lba)); goto fail;
} /* Check that sizeof_partition_entry has the correct value */ if (le32_to_cpu((*gpt)->sizeof_partition_entry) != sizeof(gpt_entry)) {
pr_debug("GUID Partition Entry Size check failed.\n"); goto fail;
}
/** *compare_gpts()-SearchdiskforvalidGPTheadersandPTEs *@pgpt:primaryGPTheader *@agpt:alternateGPTheader *@lastlba:lastLBAnumber * *Description:Returnsnothing.Sanitycheckspgptandagptfields *andprintswarningsondiscrepancies. *
*/ staticvoid
compare_gpts(gpt_header *pgpt, gpt_header *agpt, u64 lastlba)
{ int error_found = 0; if (!pgpt || !agpt) return; if (le64_to_cpu(pgpt->my_lba) != le64_to_cpu(agpt->alternate_lba)) {
pr_warn("GPT:Primary header LBA != Alt. header alternate_lba\n");
pr_warn("GPT:%lld != %lld\n",
(unsignedlonglong)le64_to_cpu(pgpt->my_lba),
(unsignedlonglong)le64_to_cpu(agpt->alternate_lba));
error_found++;
} if (le64_to_cpu(pgpt->alternate_lba) != le64_to_cpu(agpt->my_lba)) {
pr_warn("GPT:Primary header alternate_lba != Alt. header my_lba\n");
pr_warn("GPT:%lld != %lld\n",
(unsignedlonglong)le64_to_cpu(pgpt->alternate_lba),
(unsignedlonglong)le64_to_cpu(agpt->my_lba));
error_found++;
} if (le64_to_cpu(pgpt->first_usable_lba) !=
le64_to_cpu(agpt->first_usable_lba)) {
pr_warn("GPT:first_usable_lbas don't match.\n");
pr_warn("GPT:%lld != %lld\n",
(unsignedlonglong)le64_to_cpu(pgpt->first_usable_lba),
(unsignedlonglong)le64_to_cpu(agpt->first_usable_lba));
error_found++;
} if (le64_to_cpu(pgpt->last_usable_lba) !=
le64_to_cpu(agpt->last_usable_lba)) {
pr_warn("GPT:last_usable_lbas don't match.\n");
pr_warn("GPT:%lld != %lld\n",
(unsignedlonglong)le64_to_cpu(pgpt->last_usable_lba),
(unsignedlonglong)le64_to_cpu(agpt->last_usable_lba));
error_found++;
} if (efi_guidcmp(pgpt->disk_guid, agpt->disk_guid)) {
pr_warn("GPT:disk_guids don't match.\n");
error_found++;
} if (le32_to_cpu(pgpt->num_partition_entries) !=
le32_to_cpu(agpt->num_partition_entries)) {
pr_warn("GPT:num_partition_entries don't match: " "0x%x != 0x%x\n",
le32_to_cpu(pgpt->num_partition_entries),
le32_to_cpu(agpt->num_partition_entries));
error_found++;
} if (le32_to_cpu(pgpt->sizeof_partition_entry) !=
le32_to_cpu(agpt->sizeof_partition_entry)) {
pr_warn("GPT:sizeof_partition_entry values don't match: " "0x%x != 0x%x\n",
le32_to_cpu(pgpt->sizeof_partition_entry),
le32_to_cpu(agpt->sizeof_partition_entry));
error_found++;
} if (le32_to_cpu(pgpt->partition_entry_array_crc32) !=
le32_to_cpu(agpt->partition_entry_array_crc32)) {
pr_warn("GPT:partition_entry_array_crc32 values don't match: " "0x%x != 0x%x\n",
le32_to_cpu(pgpt->partition_entry_array_crc32),
le32_to_cpu(agpt->partition_entry_array_crc32));
error_found++;
} if (le64_to_cpu(pgpt->alternate_lba) != lastlba) {
pr_warn("GPT:Primary header thinks Alt. header is not at the end of the disk.\n");
pr_warn("GPT:%lld != %lld\n",
(unsignedlonglong)le64_to_cpu(pgpt->alternate_lba),
(unsignedlonglong)lastlba);
error_found++;
}
if (le64_to_cpu(agpt->my_lba) != lastlba) {
pr_warn("GPT:Alternate GPT header not at the end of the disk.\n");
pr_warn("GPT:%lld != %lld\n",
(unsignedlonglong)le64_to_cpu(agpt->my_lba),
(unsignedlonglong)lastlba);
error_found++;
}
if (error_found)
pr_warn("GPT: Use GNU Parted to correct GPT errors.\n"); return;
}
lastlba = last_lba(state->disk); if (!force_gpt) { /* This will be added to the EFI Spec. per Intel after v1.02. */
legacymbr = kzalloc(sizeof(*legacymbr), GFP_KERNEL); if (!legacymbr) goto fail;
/* If this is a RAID volume, tell md */ if (!efi_guidcmp(ptes[i].partition_type_guid, PARTITION_LINUX_RAID_GUID))
state->parts[i + 1].flags = ADDPART_FLAG_RAID;
info = &state->parts[i + 1].info;
efi_guid_to_str(&ptes[i].unique_partition_guid, info->uuid);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.