diff options
author | Luca Berra <bluca@comedia.it> | 2011-06-17 06:41:01 +0200 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2011-06-17 06:41:01 +0200 |
commit | 73e658d8ccf2ac73d795866e1b568f04cf8ee565 (patch) | |
tree | c58c09b113f68324ed1a9ed3954f7f57a55c7691 /util.c | |
parent | Fix some type-aliasing issues. (diff) | |
download | mdadm-73e658d8ccf2ac73d795866e1b568f04cf8ee565.tar.xz mdadm-73e658d8ccf2ac73d795866e1b568f04cf8ee565.zip |
Improvements to GPT reading code.
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>
Diffstat (limited to 'util.c')
-rw-r--r-- | util.c | 27 |
1 files changed, 9 insertions, 18 deletions
@@ -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; } |