Changeset View
Changeset View
Standalone View
Standalone View
sys/boot/common/part.c
Show First 20 Lines • Show All 304 Lines • ▼ Show 20 Lines | ptable_gptread(struct ptable *table, void *dev, diskread_t dread) | ||||
if (pri == 0 && sec == 0) { | if (pri == 0 && sec == 0) { | ||||
/* Both primary and backup tables are invalid. */ | /* Both primary and backup tables are invalid. */ | ||||
table->type = PTABLE_NONE; | table->type = PTABLE_NONE; | ||||
goto out; | goto out; | ||||
} | } | ||||
DEBUG("GPT detected"); | DEBUG("GPT detected"); | ||||
size = MIN(hdr.hdr_entries * hdr.hdr_entsz, | size = MIN(hdr.hdr_entries * hdr.hdr_entsz, | ||||
MAXTBLSZ * table->sectorsize); | MAXTBLSZ * table->sectorsize); | ||||
/* | |||||
* If the disk's sector count is smaller than the sector count recorded | |||||
* in the disk's GPT table header, set the table->sectors to the value | |||||
* recorded in GPT tables. This is done to work around buggy firmware | |||||
* that returns truncated disk sizes. | |||||
* | |||||
* Note, this is still not a foolproof way to get disk's size. For | |||||
* example, an image file can be truncated when copied to smaller media. | |||||
*/ | |||||
if (hdr.hdr_lba_alt + 1 > table->sectors) | |||||
table->sectors = hdr.hdr_lba_alt + 1; | |||||
for (i = 0; i < size / hdr.hdr_entsz; i++) { | for (i = 0; i < size / hdr.hdr_entsz; i++) { | ||||
ent = (struct gpt_ent *)(tbl + i * hdr.hdr_entsz); | ent = (struct gpt_ent *)(tbl + i * hdr.hdr_entsz); | ||||
if (uuid_equal(&ent->ent_type, &gpt_uuid_unused, NULL)) | if (uuid_equal(&ent->ent_type, &gpt_uuid_unused, NULL)) | ||||
continue; | continue; | ||||
/* Simple sanity checks. */ | |||||
if (ent->ent_lba_start < hdr.hdr_lba_start || | |||||
ent->ent_lba_end > hdr.hdr_lba_end || | |||||
ent->ent_lba_start > ent->ent_lba_end) | |||||
continue; | |||||
entry = malloc(sizeof(*entry)); | entry = malloc(sizeof(*entry)); | ||||
if (entry == NULL) | if (entry == NULL) | ||||
break; | break; | ||||
entry->part.start = ent->ent_lba_start; | entry->part.start = ent->ent_lba_start; | ||||
entry->part.end = ent->ent_lba_end; | entry->part.end = ent->ent_lba_end; | ||||
entry->part.index = i + 1; | entry->part.index = i + 1; | ||||
entry->part.type = gpt_parttype(ent->ent_type); | entry->part.type = gpt_parttype(ent->ent_type); | ||||
entry->flags = le64toh(ent->ent_attr); | entry->flags = le64toh(ent->ent_attr); | ||||
▲ Show 20 Lines • Show All 402 Lines • ▼ Show 20 Lines | ptable_close(struct ptable *table) | ||||
free(table); | free(table); | ||||
} | } | ||||
enum ptable_type | enum ptable_type | ||||
ptable_gettype(const struct ptable *table) | ptable_gettype(const struct ptable *table) | ||||
{ | { | ||||
return (table->type); | return (table->type); | ||||
} | |||||
int | |||||
ptable_getsize(const struct ptable *table, uint64_t *sizep) | |||||
{ | |||||
uint64_t tmp = table->sectors * table->sectorsize; | |||||
if (tmp < table->sectors) | |||||
return (EOVERFLOW); | |||||
if (sizep != NULL) | |||||
*sizep = tmp; | |||||
return (0); | |||||
} | } | ||||
int | int | ||||
ptable_getpart(const struct ptable *table, struct ptable_entry *part, int index) | ptable_getpart(const struct ptable *table, struct ptable_entry *part, int index) | ||||
{ | { | ||||
struct pentry *entry; | struct pentry *entry; | ||||
if (part == NULL || table == NULL) | if (part == NULL || table == NULL) | ||||
▲ Show 20 Lines • Show All 122 Lines • Show Last 20 Lines |