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