|
@@ -1,7 +1,9 @@
|
|
/************************************************************
|
|
/************************************************************
|
|
* EFI GUID Partition Table handling
|
|
* EFI GUID Partition Table handling
|
|
- * Per Intel EFI Specification v1.02
|
|
|
|
- * http://developer.intel.com/technology/efi/efi.htm
|
|
|
|
|
|
+ *
|
|
|
|
+ * http://www.uefi.org/specs/
|
|
|
|
+ * http://www.intel.com/technology/efi/
|
|
|
|
+ *
|
|
* efi.[ch] by Matt Domsch <Matt_Domsch@dell.com>
|
|
* efi.[ch] by Matt Domsch <Matt_Domsch@dell.com>
|
|
* Copyright 2000,2001,2002,2004 Dell Inc.
|
|
* Copyright 2000,2001,2002,2004 Dell Inc.
|
|
*
|
|
*
|
|
@@ -92,6 +94,7 @@
|
|
*
|
|
*
|
|
************************************************************/
|
|
************************************************************/
|
|
#include <linux/crc32.h>
|
|
#include <linux/crc32.h>
|
|
|
|
+#include <linux/math64.h>
|
|
#include "check.h"
|
|
#include "check.h"
|
|
#include "efi.h"
|
|
#include "efi.h"
|
|
|
|
|
|
@@ -141,7 +144,8 @@ last_lba(struct block_device *bdev)
|
|
{
|
|
{
|
|
if (!bdev || !bdev->bd_inode)
|
|
if (!bdev || !bdev->bd_inode)
|
|
return 0;
|
|
return 0;
|
|
- return (bdev->bd_inode->i_size >> 9) - 1ULL;
|
|
|
|
|
|
+ return div_u64(bdev->bd_inode->i_size,
|
|
|
|
+ bdev_logical_block_size(bdev)) - 1ULL;
|
|
}
|
|
}
|
|
|
|
|
|
static inline int
|
|
static inline int
|
|
@@ -188,6 +192,7 @@ static size_t
|
|
read_lba(struct block_device *bdev, u64 lba, u8 * buffer, size_t count)
|
|
read_lba(struct block_device *bdev, u64 lba, u8 * buffer, size_t count)
|
|
{
|
|
{
|
|
size_t totalreadcount = 0;
|
|
size_t totalreadcount = 0;
|
|
|
|
+ sector_t n = lba * (bdev_logical_block_size(bdev) / 512);
|
|
|
|
|
|
if (!bdev || !buffer || lba > last_lba(bdev))
|
|
if (!bdev || !buffer || lba > last_lba(bdev))
|
|
return 0;
|
|
return 0;
|
|
@@ -195,7 +200,7 @@ read_lba(struct block_device *bdev, u64 lba, u8 * buffer, size_t count)
|
|
while (count) {
|
|
while (count) {
|
|
int copied = 512;
|
|
int copied = 512;
|
|
Sector sect;
|
|
Sector sect;
|
|
- unsigned char *data = read_dev_sector(bdev, lba++, §);
|
|
|
|
|
|
+ unsigned char *data = read_dev_sector(bdev, n++, §);
|
|
if (!data)
|
|
if (!data)
|
|
break;
|
|
break;
|
|
if (copied > count)
|
|
if (copied > count)
|
|
@@ -601,6 +606,7 @@ efi_partition(struct parsed_partitions *state, struct block_device *bdev)
|
|
gpt_header *gpt = NULL;
|
|
gpt_header *gpt = NULL;
|
|
gpt_entry *ptes = NULL;
|
|
gpt_entry *ptes = NULL;
|
|
u32 i;
|
|
u32 i;
|
|
|
|
+ unsigned ssz = bdev_logical_block_size(bdev) / 512;
|
|
|
|
|
|
if (!find_valid_gpt(bdev, &gpt, &ptes) || !gpt || !ptes) {
|
|
if (!find_valid_gpt(bdev, &gpt, &ptes) || !gpt || !ptes) {
|
|
kfree(gpt);
|
|
kfree(gpt);
|
|
@@ -611,13 +617,14 @@ efi_partition(struct parsed_partitions *state, struct block_device *bdev)
|
|
pr_debug("GUID Partition Table is valid! Yea!\n");
|
|
pr_debug("GUID Partition Table is valid! Yea!\n");
|
|
|
|
|
|
for (i = 0; i < le32_to_cpu(gpt->num_partition_entries) && i < state->limit-1; i++) {
|
|
for (i = 0; i < le32_to_cpu(gpt->num_partition_entries) && i < state->limit-1; i++) {
|
|
|
|
+ u64 start = le64_to_cpu(ptes[i].starting_lba);
|
|
|
|
+ u64 size = le64_to_cpu(ptes[i].ending_lba) -
|
|
|
|
+ le64_to_cpu(ptes[i].starting_lba) + 1ULL;
|
|
|
|
+
|
|
if (!is_pte_valid(&ptes[i], last_lba(bdev)))
|
|
if (!is_pte_valid(&ptes[i], last_lba(bdev)))
|
|
continue;
|
|
continue;
|
|
|
|
|
|
- put_partition(state, i+1, le64_to_cpu(ptes[i].starting_lba),
|
|
|
|
- (le64_to_cpu(ptes[i].ending_lba) -
|
|
|
|
- le64_to_cpu(ptes[i].starting_lba) +
|
|
|
|
- 1ULL));
|
|
|
|
|
|
+ put_partition(state, i+1, start * ssz, size * ssz);
|
|
|
|
|
|
/* If this is a RAID volume, tell md */
|
|
/* If this is a RAID volume, tell md */
|
|
if (!efi_guidcmp(ptes[i].partition_type_guid,
|
|
if (!efi_guidcmp(ptes[i].partition_type_guid,
|