From f63be03880f3667f2fb75acaa02f633e265e01e5 Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Mon, 15 Apr 2013 09:12:14 +0200 Subject: [PATCH 318/482] * grub-core/disk/efi/efidisk.c: Limit disk read or write chunk to 0x500 sectors. Based on patch by Peter Jones. --- ChangeLog | 7 +++++++ grub-core/disk/efi/efidisk.c | 50 +++++++++++++++++++++++++++++--------------- 2 files changed, 40 insertions(+), 17 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2dcf1f5..6f33ff1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,11 @@ 2013-04-15 Vladimir Serbinenko +2013-04-15 Peter Jones + + * grub-core/disk/efi/efidisk.c: Limit disk read or write chunk to 0x500 + sectors. + Based on patch by Peter Jones. + +2013-04-15 Vladimir Serbinenko Fix DMRAID partition handling. diff --git a/grub-core/disk/efi/efidisk.c b/grub-core/disk/efi/efidisk.c index 28b9fa1..5a6fc63 100644 --- a/grub-core/disk/efi/efidisk.c +++ b/grub-core/disk/efi/efidisk.c @@ -528,9 +528,9 @@ grub_efidisk_close (struct grub_disk *disk __attribute__ ((unused))) grub_dprintf ("efidisk", "closing %s\n", disk->name); } -static grub_err_t -grub_efidisk_read (struct grub_disk *disk, grub_disk_addr_t sector, - grub_size_t size, char *buf) +static grub_efi_status_t +grub_efidisk_readwrite (struct grub_disk *disk, grub_disk_addr_t sector, + grub_size_t size, char *buf, int wr) { /* For now, use the disk io interface rather than the block io's. */ struct grub_efidisk_data *d; @@ -540,14 +540,38 @@ grub_efidisk_read (struct grub_disk *disk, grub_disk_addr_t sector, d = disk->data; bio = d->block_io; + while (size > 0) + { + grub_size_t len; + len = 0x500; + if (len > size) + len = size; + status = efi_call_5 ((wr ? bio->write_blocks : bio->read_blocks), bio, + bio->media->media_id, + (grub_efi_uint64_t) sector, + (grub_efi_uintn_t) size << disk->log_sector_size, + buf); + size -= len; + buf += len << disk->log_sector_size; + sector += len; + if (status != GRUB_EFI_SUCCESS) + return status; + } + return GRUB_EFI_SUCCESS; +} + +static grub_err_t +grub_efidisk_read (struct grub_disk *disk, grub_disk_addr_t sector, + grub_size_t size, char *buf) +{ + grub_efi_status_t status; + grub_dprintf ("efidisk", "reading 0x%lx sectors at the sector 0x%llx from %s\n", (unsigned long) size, (unsigned long long) sector, disk->name); - status = efi_call_5 (bio->read_blocks, bio, bio->media->media_id, - (grub_efi_uint64_t) sector, - (grub_efi_uintn_t) size << disk->log_sector_size, - buf); + status = grub_efidisk_readwrite (disk, sector, size, buf, 0); + if (status != GRUB_EFI_SUCCESS) return grub_error (GRUB_ERR_READ_ERROR, N_("failure reading sector 0x%llx from `%s'"), @@ -561,22 +585,14 @@ static grub_err_t grub_efidisk_write (struct grub_disk *disk, grub_disk_addr_t sector, grub_size_t size, const char *buf) { - /* For now, use the disk io interface rather than the block io's. */ - struct grub_efidisk_data *d; - grub_efi_block_io_t *bio; grub_efi_status_t status; - d = disk->data; - bio = d->block_io; - grub_dprintf ("efidisk", "writing 0x%lx sectors at the sector 0x%llx to %s\n", (unsigned long) size, (unsigned long long) sector, disk->name); - status = efi_call_5 (bio->write_blocks, bio, bio->media->media_id, - (grub_efi_uint64_t) sector, - (grub_efi_uintn_t) size << disk->log_sector_size, - (void *) buf); + status = grub_efidisk_readwrite (disk, sector, size, (char *) buf, 1); + if (status != GRUB_EFI_SUCCESS) return grub_error (GRUB_ERR_WRITE_ERROR, N_("failure writing sector 0x%llx to `%s'"), -- 1.8.2.1