]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
Improvements to GPT reading code.
authorLuca Berra <bluca@comedia.it>
Fri, 17 Jun 2011 04:41:01 +0000 (14:41 +1000)
committerNeilBrown <neilb@suse.de>
Fri, 17 Jun 2011 04:41:01 +0000 (14:41 +1000)
looking at the gpt code in util.c i found i did not like it at all, a
gpt partition entry is currently 128 bytes, but the spec does not say it
is a fixed value, so the code that reads into a buffer with 512bytes
chunk expecting this to be a multiplier of part_size is imho incorrect.
my fix was to read each partition entry directly into a struct
GPT_part_entry, the advantage is that the code is very simple to read,
the disadvantage it is 128 reads of 128 bytes each, which is
sub-optimal, but i believe readahead will mitigate this a lot.

Signed-off-by: NeilBrown <neilb@suse.de>
util.c

diff --git a/util.c b/util.c
index e92be4fe608a214f4be96f6013e97f657b7ecc58..10bbe56a4785b410ba7e243d84208015f42ccae3 100644 (file)
--- a/util.c
+++ b/util.c
@@ -1119,9 +1119,8 @@ int must_be_container(int fd)
 static int get_gpt_last_partition_end(int fd, unsigned long long *endofpart)
 {
        struct GPT gpt;
-       unsigned char buf[512];
        unsigned char empty_gpt_entry[16]= {0};
-       struct GPT_part_entry *part;
+       struct GPT_part_entry part;
        unsigned long long curr_part_end;
        unsigned all_partitions, entry_size;
        unsigned part_nr;
@@ -1129,8 +1128,9 @@ static int get_gpt_last_partition_end(int fd, unsigned long long *endofpart)
        *endofpart = 0;
 
        BUILD_BUG_ON(sizeof(gpt) != 512);
-       /* read GPT header */
+       /* skip protective MBR */
        lseek(fd, 512, SEEK_SET);
+       /* read GPT header */
        if (read(fd, &gpt, 512) != 512)
                return 0;
 
@@ -1147,28 +1147,19 @@ static int get_gpt_last_partition_end(int fd, unsigned long long *endofpart)
            entry_size > 512)
                return -1;
 
-       /* read first GPT partition entries */
-       if (read(fd, buf, 512) != 512)
-               return 0;
-
-       part = (struct GPT_part_entry*)buf;
-
        for (part_nr=0; part_nr < all_partitions; part_nr++) {
+               /* read partition entry */
+               if (read(fd, &part, entry_size) != (ssize_t)entry_size)
+                       return 0;
+
                /* is this valid partition? */
-               if (memcmp(part->type_guid, empty_gpt_entry, 16) != 0) {
+               if (memcmp(part.type_guid, empty_gpt_entry, 16) != 0) {
                        /* check the last lba for the current partition */
-                       curr_part_end = __le64_to_cpu(part->ending_lba);
+                       curr_part_end = __le64_to_cpu(part.ending_lba);
                        if (curr_part_end > *endofpart)
                                *endofpart = curr_part_end;
                }
 
-               part = (struct GPT_part_entry*)((unsigned char*)part + entry_size);
-
-               if ((unsigned char *)part >= buf + 512) {
-                       if (read(fd, buf, 512) != 512)
-                               return 0;
-                       part = (struct GPT_part_entry*)buf;
-               }
        }
        return 1;
 }