Index: sys/boot/common/disk.c =================================================================== --- sys/boot/common/disk.c +++ sys/boot/common/disk.c @@ -46,6 +46,7 @@ struct open_disk { struct ptable *table; off_t mediasize; + off_t entrysize; u_int sectorsize; u_int flags; int rcnt; @@ -264,13 +265,28 @@ } int -disk_ioctl(struct disk_devdesc *dev, u_long cmd, void *buf) +disk_ioctl(struct disk_devdesc *dev, u_long cmd, void *data) { + struct open_disk *od = dev->d_opendata; - if (dev->d_dev->dv_ioctl) - return ((*dev->d_dev->dv_ioctl)(dev->d_opendata, cmd, buf)); + if (od == NULL) + return (ENOTTY); - return (ENXIO); + switch (cmd) { + case DIOCGSECTORSIZE: + *(u_int *)data = od->sectorsize; + break; + case DIOCGMEDIASIZE: + if (dev->d_offset == 0) + *(off_t *)data = od->mediasize; + else + *(off_t *)data = od->entrysize * od->sectorsize; + break; + default: + return (ENOTTY); + } + + return (0); } int @@ -315,6 +331,7 @@ } dev->d_opendata = od; od->rcnt = 0; + od->entrysize = 0; } od->mediasize = mediasize; od->sectorsize = sectorsize; @@ -330,14 +347,20 @@ rc = ENXIO; goto out; } + mediasize = ptable_getsize(od->table); + if (mediasize > od->mediasize) { + od->mediasize = mediasize; + } opened: rc = 0; if (ptable_gettype(od->table) == PTABLE_BSD && partition >= 0) { /* It doesn't matter what value has d_slice */ rc = ptable_getpart(od->table, &part, partition); - if (rc == 0) + if (rc == 0) { dev->d_offset = part.start; + od->entrysize = part.end - part.start + 1; + } } else if (slice >= 0) { /* Try to get information about partition */ if (slice == 0) @@ -347,6 +370,7 @@ if (rc != 0) /* Partition doesn't exist */ goto out; dev->d_offset = part.start; + od->entrysize = part.end - part.start + 1; slice = part.index; if (ptable_gettype(od->table) == PTABLE_GPT) { partition = 255; @@ -389,6 +413,7 @@ if (rc != 0) goto out; dev->d_offset += part.start; + od->entrysize = part.end - part.start + 1; } out: if (table != NULL) Index: sys/boot/common/part.h =================================================================== --- sys/boot/common/part.h +++ sys/boot/common/part.h @@ -70,6 +70,7 @@ diskread_t *dread); void ptable_close(struct ptable *table); enum ptable_type ptable_gettype(const struct ptable *table); +uint64_t ptable_getsize(const struct ptable *table); int ptable_getpart(const struct ptable *table, struct ptable_entry *part, int index); Index: sys/boot/common/part.c =================================================================== --- sys/boot/common/part.c +++ sys/boot/common/part.c @@ -310,6 +310,11 @@ DEBUG("GPT detected"); size = MIN(hdr.hdr_entries * hdr.hdr_entsz, MAXTBLSZ * table->sectorsize); + + /* Reset table->sectors if needed. */ + if (hdr.hdr_lba_alt + 1 > table->sectors) + table->sectors = hdr.hdr_lba_alt + 1; + for (i = 0; i < size / hdr.hdr_entsz; i++) { ent = (struct gpt_ent *)(tbl + i * hdr.hdr_entsz); if (uuid_equal(&ent->ent_type, &gpt_uuid_unused, NULL)) @@ -734,6 +739,13 @@ return (table->type); } +uint64_t +ptable_getsize(const struct ptable *table) +{ + + return (table->sectors * table->sectorsize); +} + int ptable_getpart(const struct ptable *table, struct ptable_entry *part, int index) {