aboutsummaryrefslogtreecommitdiffstats
path: root/block/partitions
diff options
context:
space:
mode:
authorDavidlohr Bueso <davidlohr@hp.com>2013-09-11 17:25:00 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-09-11 18:59:17 -0400
commit27a7c642174eaec627f6a3a254035bf8abd02c5e (patch)
tree19311875531607830f626c6ff7498969bccdc669 /block/partitions
parentb05ebbbbeb67a420d06567c6b9618a9e644d6104 (diff)
partitions/efi: account for pmbr size in lba
The partition that has the 0xEE (GPT protective), must have the size in lba field set to the lesser of the size of the disk minus one or 0xFFFFFFFF for larger disks. Signed-off-by: Davidlohr Bueso <davidlohr@hp.com> Reviewed-by: Karel Zak <kzak@redhat.com> Acked-by: Matt Fleming <matt.fleming@intel.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'block/partitions')
-rw-r--r--block/partitions/efi.c21
1 files changed, 18 insertions, 3 deletions
diff --git a/block/partitions/efi.c b/block/partitions/efi.c
index e3cb4f19cf6d..b028af688361 100644
--- a/block/partitions/efi.c
+++ b/block/partitions/efi.c
@@ -166,6 +166,7 @@ invalid:
166/** 166/**
167 * is_pmbr_valid(): test Protective MBR for validity 167 * is_pmbr_valid(): test Protective MBR for validity
168 * @mbr: pointer to a legacy mbr structure 168 * @mbr: pointer to a legacy mbr structure
169 * @total_sectors: amount of sectors in the device
169 * 170 *
170 * Description: Checks for a valid protective or hybrid 171 * Description: Checks for a valid protective or hybrid
171 * master boot record (MBR). The validity of a pMBR depends 172 * master boot record (MBR). The validity of a pMBR depends
@@ -180,9 +181,9 @@ invalid:
180 * Returns 0 upon invalid MBR, or GPT_MBR_PROTECTIVE or 181 * Returns 0 upon invalid MBR, or GPT_MBR_PROTECTIVE or
181 * GPT_MBR_HYBRID depending on the device layout. 182 * GPT_MBR_HYBRID depending on the device layout.
182 */ 183 */
183static int is_pmbr_valid(legacy_mbr *mbr) 184static int is_pmbr_valid(legacy_mbr *mbr, sector_t total_sectors)
184{ 185{
185 int i, ret = 0; /* invalid by default */ 186 int i, part = 0, ret = 0; /* invalid by default */
186 187
187 if (!mbr || le16_to_cpu(mbr->signature) != MSDOS_MBR_SIGNATURE) 188 if (!mbr || le16_to_cpu(mbr->signature) != MSDOS_MBR_SIGNATURE)
188 goto done; 189 goto done;
@@ -190,6 +191,7 @@ static int is_pmbr_valid(legacy_mbr *mbr)
190 for (i = 0; i < 4; i++) { 191 for (i = 0; i < 4; i++) {
191 ret = pmbr_part_valid(&mbr->partition_record[i]); 192 ret = pmbr_part_valid(&mbr->partition_record[i]);
192 if (ret == GPT_MBR_PROTECTIVE) { 193 if (ret == GPT_MBR_PROTECTIVE) {
194 part = i;
193 /* 195 /*
194 * Ok, we at least know that there's a protective MBR, 196 * Ok, we at least know that there's a protective MBR,
195 * now check if there are other partition types for 197 * now check if there are other partition types for
@@ -207,6 +209,18 @@ check_hybrid:
207 EFI_PMBR_OSTYPE_EFI_GPT) && 209 EFI_PMBR_OSTYPE_EFI_GPT) &&
208 (mbr->partition_record[i].os_type != 0x00)) 210 (mbr->partition_record[i].os_type != 0x00))
209 ret = GPT_MBR_HYBRID; 211 ret = GPT_MBR_HYBRID;
212
213 /*
214 * Protective MBRs take up the lesser of the whole disk
215 * or 2 TiB (32bit LBA), ignoring the rest of the disk.
216 *
217 * Hybrid MBRs do not necessarily comply with this.
218 */
219 if (ret == GPT_MBR_PROTECTIVE) {
220 if (le32_to_cpu(mbr->partition_record[part].size_in_lba) !=
221 min((uint32_t) total_sectors - 1, 0xFFFFFFFF))
222 ret = 0;
223 }
210done: 224done:
211 return ret; 225 return ret;
212} 226}
@@ -568,6 +582,7 @@ static int find_valid_gpt(struct parsed_partitions *state, gpt_header **gpt,
568 gpt_header *pgpt = NULL, *agpt = NULL; 582 gpt_header *pgpt = NULL, *agpt = NULL;
569 gpt_entry *pptes = NULL, *aptes = NULL; 583 gpt_entry *pptes = NULL, *aptes = NULL;
570 legacy_mbr *legacymbr; 584 legacy_mbr *legacymbr;
585 sector_t total_sectors = i_size_read(state->bdev->bd_inode) >> 9;
571 u64 lastlba; 586 u64 lastlba;
572 587
573 if (!ptes) 588 if (!ptes)
@@ -581,7 +596,7 @@ static int find_valid_gpt(struct parsed_partitions *state, gpt_header **gpt,
581 goto fail; 596 goto fail;
582 597
583 read_lba(state, 0, (u8 *)legacymbr, sizeof(*legacymbr)); 598 read_lba(state, 0, (u8 *)legacymbr, sizeof(*legacymbr));
584 good_pmbr = is_pmbr_valid(legacymbr); 599 good_pmbr = is_pmbr_valid(legacymbr, total_sectors);
585 kfree(legacymbr); 600 kfree(legacymbr);
586 601
587 if (!good_pmbr) 602 if (!good_pmbr)