aboutsummaryrefslogtreecommitdiffstats
path: root/fs/partitions/efi.c
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /fs/partitions/efi.c
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff)
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'fs/partitions/efi.c')
-rw-r--r--fs/partitions/efi.c31
1 files changed, 20 insertions, 11 deletions
diff --git a/fs/partitions/efi.c b/fs/partitions/efi.c
index 038a6022152f..91babdae7587 100644
--- a/fs/partitions/efi.c
+++ b/fs/partitions/efi.c
@@ -1,7 +1,9 @@
1/************************************************************ 1/************************************************************
2 * EFI GUID Partition Table handling 2 * EFI GUID Partition Table handling
3 * Per Intel EFI Specification v1.02 3 *
4 * http://developer.intel.com/technology/efi/efi.htm 4 * http://www.uefi.org/specs/
5 * http://www.intel.com/technology/efi/
6 *
5 * efi.[ch] by Matt Domsch <Matt_Domsch@dell.com> 7 * efi.[ch] by Matt Domsch <Matt_Domsch@dell.com>
6 * Copyright 2000,2001,2002,2004 Dell Inc. 8 * Copyright 2000,2001,2002,2004 Dell Inc.
7 * 9 *
@@ -92,6 +94,8 @@
92 * 94 *
93 ************************************************************/ 95 ************************************************************/
94#include <linux/crc32.h> 96#include <linux/crc32.h>
97#include <linux/math64.h>
98#include <linux/slab.h>
95#include "check.h" 99#include "check.h"
96#include "efi.h" 100#include "efi.h"
97 101
@@ -141,7 +145,8 @@ last_lba(struct block_device *bdev)
141{ 145{
142 if (!bdev || !bdev->bd_inode) 146 if (!bdev || !bdev->bd_inode)
143 return 0; 147 return 0;
144 return (bdev->bd_inode->i_size >> 9) - 1ULL; 148 return div_u64(bdev->bd_inode->i_size,
149 bdev_logical_block_size(bdev)) - 1ULL;
145} 150}
146 151
147static inline int 152static inline int
@@ -188,6 +193,7 @@ static size_t
188read_lba(struct block_device *bdev, u64 lba, u8 * buffer, size_t count) 193read_lba(struct block_device *bdev, u64 lba, u8 * buffer, size_t count)
189{ 194{
190 size_t totalreadcount = 0; 195 size_t totalreadcount = 0;
196 sector_t n = lba * (bdev_logical_block_size(bdev) / 512);
191 197
192 if (!bdev || !buffer || lba > last_lba(bdev)) 198 if (!bdev || !buffer || lba > last_lba(bdev))
193 return 0; 199 return 0;
@@ -195,7 +201,7 @@ read_lba(struct block_device *bdev, u64 lba, u8 * buffer, size_t count)
195 while (count) { 201 while (count) {
196 int copied = 512; 202 int copied = 512;
197 Sector sect; 203 Sector sect;
198 unsigned char *data = read_dev_sector(bdev, lba++, &sect); 204 unsigned char *data = read_dev_sector(bdev, n++, &sect);
199 if (!data) 205 if (!data)
200 break; 206 break;
201 if (copied > count) 207 if (copied > count)
@@ -257,15 +263,16 @@ static gpt_header *
257alloc_read_gpt_header(struct block_device *bdev, u64 lba) 263alloc_read_gpt_header(struct block_device *bdev, u64 lba)
258{ 264{
259 gpt_header *gpt; 265 gpt_header *gpt;
266 unsigned ssz = bdev_logical_block_size(bdev);
267
260 if (!bdev) 268 if (!bdev)
261 return NULL; 269 return NULL;
262 270
263 gpt = kzalloc(sizeof (gpt_header), GFP_KERNEL); 271 gpt = kzalloc(ssz, GFP_KERNEL);
264 if (!gpt) 272 if (!gpt)
265 return NULL; 273 return NULL;
266 274
267 if (read_lba(bdev, lba, (u8 *) gpt, 275 if (read_lba(bdev, lba, (u8 *) gpt, ssz) < ssz) {
268 sizeof (gpt_header)) < sizeof (gpt_header)) {
269 kfree(gpt); 276 kfree(gpt);
270 gpt=NULL; 277 gpt=NULL;
271 return NULL; 278 return NULL;
@@ -601,6 +608,7 @@ efi_partition(struct parsed_partitions *state, struct block_device *bdev)
601 gpt_header *gpt = NULL; 608 gpt_header *gpt = NULL;
602 gpt_entry *ptes = NULL; 609 gpt_entry *ptes = NULL;
603 u32 i; 610 u32 i;
611 unsigned ssz = bdev_logical_block_size(bdev) / 512;
604 612
605 if (!find_valid_gpt(bdev, &gpt, &ptes) || !gpt || !ptes) { 613 if (!find_valid_gpt(bdev, &gpt, &ptes) || !gpt || !ptes) {
606 kfree(gpt); 614 kfree(gpt);
@@ -611,13 +619,14 @@ efi_partition(struct parsed_partitions *state, struct block_device *bdev)
611 pr_debug("GUID Partition Table is valid! Yea!\n"); 619 pr_debug("GUID Partition Table is valid! Yea!\n");
612 620
613 for (i = 0; i < le32_to_cpu(gpt->num_partition_entries) && i < state->limit-1; i++) { 621 for (i = 0; i < le32_to_cpu(gpt->num_partition_entries) && i < state->limit-1; i++) {
622 u64 start = le64_to_cpu(ptes[i].starting_lba);
623 u64 size = le64_to_cpu(ptes[i].ending_lba) -
624 le64_to_cpu(ptes[i].starting_lba) + 1ULL;
625
614 if (!is_pte_valid(&ptes[i], last_lba(bdev))) 626 if (!is_pte_valid(&ptes[i], last_lba(bdev)))
615 continue; 627 continue;
616 628
617 put_partition(state, i+1, le64_to_cpu(ptes[i].starting_lba), 629 put_partition(state, i+1, start * ssz, size * ssz);
618 (le64_to_cpu(ptes[i].ending_lba) -
619 le64_to_cpu(ptes[i].starting_lba) +
620 1ULL));
621 630
622 /* If this is a RAID volume, tell md */ 631 /* If this is a RAID volume, tell md */
623 if (!efi_guidcmp(ptes[i].partition_type_guid, 632 if (!efi_guidcmp(ptes[i].partition_type_guid,