sysfs: Implement sysfs_getattr & sysfs_permission
[safe/jmp/linux-2.6] / fs / partitions / efi.c
index 0f5b017..49cfd5f 100644 (file)
@@ -1,7 +1,9 @@
 /************************************************************
  * 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>
  *   Copyright 2000,2001,2002,2004 Dell Inc.
  *
  * - Code works, detects all the partitions.
  *
  ************************************************************/
-#include <linux/config.h>
 #include <linux/crc32.h>
+#include <linux/math64.h>
 #include "check.h"
 #include "efi.h"
 
-#undef EFI_DEBUG
-#ifdef EFI_DEBUG
-#define Dprintk(x...) printk(KERN_DEBUG x)
-#else
-#define Dprintk(x...)
-#endif
-
 /* This allows a kernel command line option 'gpt' to override
  * the test for invalid PMBR.  Not __initdata because reloading
  * the partition tables happens after init too.
@@ -149,11 +144,12 @@ last_lba(struct block_device *bdev)
 {
        if (!bdev || !bdev->bd_inode)
                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
-pmbr_part_valid(struct partition *part, u64 lastlba)
+pmbr_part_valid(struct partition *part)
 {
         if (part->sys_ind == EFI_PMBR_OSTYPE_EFI_GPT &&
             le32_to_cpu(part->start_sect) == 1UL)
@@ -164,7 +160,6 @@ pmbr_part_valid(struct partition *part, u64 lastlba)
 /**
  * is_pmbr_valid(): test Protective MBR for validity
  * @mbr: pointer to a legacy mbr structure
- * @lastlba: last_lba for the whole device
  *
  * Description: Returns 1 if PMBR is valid, 0 otherwise.
  * Validity depends on two things:
@@ -172,13 +167,13 @@ pmbr_part_valid(struct partition *part, u64 lastlba)
  *  2) One partition of type 0xEE is found
  */
 static int
-is_pmbr_valid(legacy_mbr *mbr, u64 lastlba)
+is_pmbr_valid(legacy_mbr *mbr)
 {
        int i;
        if (!mbr || le16_to_cpu(mbr->signature) != MSDOS_MBR_SIGNATURE)
                 return 0;
        for (i = 0; i < 4; i++)
-               if (pmbr_part_valid(&mbr->partition_record[i], lastlba))
+               if (pmbr_part_valid(&mbr->partition_record[i]))
                         return 1;
        return 0;
 }
@@ -197,6 +192,7 @@ static size_t
 read_lba(struct block_device *bdev, u64 lba, u8 * buffer, size_t count)
 {
        size_t totalreadcount = 0;
+       sector_t n = lba * (bdev_logical_block_size(bdev) / 512);
 
        if (!bdev || !buffer || lba > last_lba(bdev))
                 return 0;
@@ -204,7 +200,7 @@ read_lba(struct block_device *bdev, u64 lba, u8 * buffer, size_t count)
        while (count) {
                int copied = 512;
                Sector sect;
-               unsigned char *data = read_dev_sector(bdev, lba++, &sect);
+               unsigned char *data = read_dev_sector(bdev, n++, &sect);
                if (!data)
                        break;
                if (copied > count)
@@ -239,10 +235,9 @@ alloc_read_gpt_entries(struct block_device *bdev, gpt_header *gpt)
                 le32_to_cpu(gpt->sizeof_partition_entry);
        if (!count)
                return NULL;
-       pte = kmalloc(count, GFP_KERNEL);
+       pte = kzalloc(count, GFP_KERNEL);
        if (!pte)
                return NULL;
-       memset(pte, 0, count);
 
        if (read_lba(bdev, le64_to_cpu(gpt->partition_entry_lba),
                      (u8 *) pte,
@@ -267,16 +262,16 @@ static gpt_header *
 alloc_read_gpt_header(struct block_device *bdev, u64 lba)
 {
        gpt_header *gpt;
+       unsigned ssz = bdev_logical_block_size(bdev);
+
        if (!bdev)
                return NULL;
 
-       gpt = kmalloc(sizeof (gpt_header), GFP_KERNEL);
+       gpt = kzalloc(ssz, GFP_KERNEL);
        if (!gpt)
                return NULL;
-       memset(gpt, 0, sizeof (gpt_header));
 
-       if (read_lba(bdev, lba, (u8 *) gpt,
-                    sizeof (gpt_header)) < sizeof (gpt_header)) {
+       if (read_lba(bdev, lba, (u8 *) gpt, ssz) < ssz) {
                kfree(gpt);
                 gpt=NULL;
                return NULL;
@@ -309,10 +304,10 @@ is_gpt_valid(struct block_device *bdev, u64 lba,
 
        /* Check the GUID Partition Table signature */
        if (le64_to_cpu((*gpt)->signature) != GPT_HEADER_SIGNATURE) {
-               Dprintk("GUID Partition Table Header signature is wrong:"
-                       "%lld != %lld\n",
-                       (unsigned long long)le64_to_cpu((*gpt)->signature),
-                       (unsigned long long)GPT_HEADER_SIGNATURE);
+               pr_debug("GUID Partition Table Header signature is wrong:"
+                        "%lld != %lld\n",
+                        (unsigned long long)le64_to_cpu((*gpt)->signature),
+                        (unsigned long long)GPT_HEADER_SIGNATURE);
                goto fail;
        }
 
@@ -322,9 +317,8 @@ is_gpt_valid(struct block_device *bdev, u64 lba,
        crc = efi_crc32((const unsigned char *) (*gpt), le32_to_cpu((*gpt)->header_size));
 
        if (crc != origcrc) {
-               Dprintk
-                   ("GUID Partition Table Header CRC is wrong: %x != %x\n",
-                    crc, origcrc);
+               pr_debug("GUID Partition Table Header CRC is wrong: %x != %x\n",
+                        crc, origcrc);
                goto fail;
        }
        (*gpt)->header_crc32 = cpu_to_le32(origcrc);
@@ -332,9 +326,9 @@ is_gpt_valid(struct block_device *bdev, u64 lba,
        /* Check that the my_lba entry points to the LBA that contains
         * the GUID Partition Table */
        if (le64_to_cpu((*gpt)->my_lba) != lba) {
-               Dprintk("GPT my_lba incorrect: %lld != %lld\n",
-                       (unsigned long long)le64_to_cpu((*gpt)->my_lba),
-                       (unsigned long long)lba);
+               pr_debug("GPT my_lba incorrect: %lld != %lld\n",
+                        (unsigned long long)le64_to_cpu((*gpt)->my_lba),
+                        (unsigned long long)lba);
                goto fail;
        }
 
@@ -343,15 +337,15 @@ is_gpt_valid(struct block_device *bdev, u64 lba,
         */
        lastlba = last_lba(bdev);
        if (le64_to_cpu((*gpt)->first_usable_lba) > lastlba) {
-               Dprintk("GPT: first_usable_lba incorrect: %lld > %lld\n",
-                       (unsigned long long)le64_to_cpu((*gpt)->first_usable_lba),
-                       (unsigned long long)lastlba);
+               pr_debug("GPT: first_usable_lba incorrect: %lld > %lld\n",
+                        (unsigned long long)le64_to_cpu((*gpt)->first_usable_lba),
+                        (unsigned long long)lastlba);
                goto fail;
        }
        if (le64_to_cpu((*gpt)->last_usable_lba) > lastlba) {
-               Dprintk("GPT: last_usable_lba incorrect: %lld > %lld\n",
-                       (unsigned long long)le64_to_cpu((*gpt)->last_usable_lba),
-                       (unsigned long long)lastlba);
+               pr_debug("GPT: last_usable_lba incorrect: %lld > %lld\n",
+                        (unsigned long long)le64_to_cpu((*gpt)->last_usable_lba),
+                        (unsigned long long)lastlba);
                goto fail;
        }
 
@@ -364,7 +358,7 @@ is_gpt_valid(struct block_device *bdev, u64 lba,
                        le32_to_cpu((*gpt)->sizeof_partition_entry));
 
        if (crc != le32_to_cpu((*gpt)->partition_entry_array_crc32)) {
-               Dprintk("GUID Partitition Entry Array CRC check failed.\n");
+               pr_debug("GUID Partitition Entry Array CRC check failed.\n");
                goto fail_ptes;
        }
 
@@ -519,7 +513,7 @@ find_valid_gpt(struct block_device *bdev, gpt_header **gpt, gpt_entry **ptes)
        int good_pgpt = 0, good_agpt = 0, good_pmbr = 0;
        gpt_header *pgpt = NULL, *agpt = NULL;
        gpt_entry *pptes = NULL, *aptes = NULL;
-       legacy_mbr *legacymbr = NULL;
+       legacy_mbr *legacymbr;
        u64 lastlba;
        if (!bdev || !gpt || !ptes)
                return 0;
@@ -527,14 +521,12 @@ find_valid_gpt(struct block_device *bdev, gpt_header **gpt, gpt_entry **ptes)
        lastlba = last_lba(bdev);
         if (!force_gpt) {
                 /* This will be added to the EFI Spec. per Intel after v1.02. */
-                legacymbr = kmalloc(sizeof (*legacymbr), GFP_KERNEL);
+                legacymbr = kzalloc(sizeof (*legacymbr), GFP_KERNEL);
                 if (legacymbr) {
-                        memset(legacymbr, 0, sizeof (*legacymbr));
                         read_lba(bdev, 0, (u8 *) legacymbr,
                                  sizeof (*legacymbr));
-                        good_pmbr = is_pmbr_valid(legacymbr, lastlba);
+                        good_pmbr = is_pmbr_valid(legacymbr);
                         kfree(legacymbr);
-                        legacymbr=NULL;
                 }
                 if (!good_pmbr)
                         goto fail;
@@ -615,6 +607,7 @@ efi_partition(struct parsed_partitions *state, struct block_device *bdev)
        gpt_header *gpt = NULL;
        gpt_entry *ptes = NULL;
        u32 i;
+       unsigned ssz = bdev_logical_block_size(bdev) / 512;
 
        if (!find_valid_gpt(bdev, &gpt, &ptes) || !gpt || !ptes) {
                kfree(gpt);
@@ -622,16 +615,17 @@ efi_partition(struct parsed_partitions *state, struct block_device *bdev)
                return 0;
        }
 
-       Dprintk("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++) {
+               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)))
                        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 (!efi_guidcmp(ptes[i].partition_type_guid,