Index: head/sys/boot/efi/libefi/efipart.c =================================================================== --- head/sys/boot/efi/libefi/efipart.c +++ head/sys/boot/efi/libefi/efipart.c @@ -834,8 +834,10 @@ return (ENOSYS); } - if (EFI_ERROR(status)) - printf("%s: rw=%d, status=%lu\n", __func__, rw, (u_long)status); + if (EFI_ERROR(status)) { + printf("%s: rw=%d, blk=%ju size=%ju status=%lu\n", __func__, rw, + blk, nblks, EFI_ERROR_CODE(status)); + } return (efi_status_to_errno(status)); } @@ -859,6 +861,10 @@ if (pd == NULL) return (EINVAL); + if (pd->pd_blkio->Media->RemovableMedia && + !pd->pd_blkio->Media->MediaPresent) + return (EIO); + bcd.dv_strategy = efipart_realstrategy; bcd.dv_devdata = devdata; bcd.dv_cache = pd->pd_bcache; @@ -878,7 +884,7 @@ pdinfo_list_t *pdi; pdinfo_t *pd; EFI_BLOCK_IO *blkio; - off_t off; + uint64_t off, disk_blocks, d_offset = 0; char *blkbuf; size_t blkoff, blksz; int error; @@ -902,11 +908,24 @@ return (EIO); off = blk * 512; + /* + * Get disk blocks, this value is either for whole disk or for + * partition. + */ + disk_blocks = 0; + if (dev->d_dev->dv_type == DEVT_DISK) { + if (disk_ioctl(dev, DIOCGMEDIASIZE, &disk_blocks) == 0) { + /* DIOCGMEDIASIZE does return bytes. */ + disk_blocks /= blkio->Media->BlockSize; + } + d_offset = dev->d_offset; + } + if (disk_blocks == 0) + disk_blocks = blkio->Media->LastBlock + 1 - d_offset; + /* make sure we don't read past disk end */ - if ((off + size) / blkio->Media->BlockSize - 1 > - blkio->Media->LastBlock) { - size = blkio->Media->LastBlock + 1 - - off / blkio->Media->BlockSize; + if ((off + size) / blkio->Media->BlockSize > d_offset + disk_blocks) { + size = d_offset + disk_blocks - off / blkio->Media->BlockSize; size = size * blkio->Media->BlockSize; } @@ -914,9 +933,9 @@ *rsize = size; if ((size % blkio->Media->BlockSize == 0) && - ((blk * 512) % blkio->Media->BlockSize == 0)) + (off % blkio->Media->BlockSize == 0)) return (efipart_readwrite(blkio, rw, - blk * 512 / blkio->Media->BlockSize, + off / blkio->Media->BlockSize, size / blkio->Media->BlockSize, buf)); /*