Blame SOURCES/efibootmgr-0.5.4-support-4k-sectors.patch

8dd33d
Return-Path: pjones@redhat.com
8dd33d
Received: from zmta02.collab.prod.int.phx2.redhat.com (LHLO
8dd33d
 zmta02.collab.prod.int.phx2.redhat.com) (10.5.5.32) by
8dd33d
 mail04.corp.redhat.com with LMTP; Wed, 14 Jul 2010 14:25:52 -0400 (EDT)
8dd33d
Received: from localhost (localhost.localdomain [127.0.0.1])
8dd33d
	by zmta02.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id B69C19F152
8dd33d
	for <pjones@redhat.com>; Wed, 14 Jul 2010 14:25:52 -0400 (EDT)
8dd33d
Received: from zmta02.collab.prod.int.phx2.redhat.com ([127.0.0.1])
8dd33d
	by localhost (zmta02.collab.prod.int.phx2.redhat.com [127.0.0.1]) (amavisd-new, port 10024)
8dd33d
	with ESMTP id jCHcGZehMQ5J for <pjones@redhat.com>;
8dd33d
	Wed, 14 Jul 2010 14:25:52 -0400 (EDT)
8dd33d
Received: from int-mx08.intmail.prod.int.phx2.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.21])
8dd33d
	by zmta02.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id A601C9F14C
8dd33d
	for <pjones@mail.corp.redhat.com>; Wed, 14 Jul 2010 14:25:52 -0400 (EDT)
8dd33d
Received: from pjones4.install.bos.redhat.com (pjones4.install.bos.redhat.com [10.16.52.154])
8dd33d
	by int-mx08.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o6EIPpGh017771;
8dd33d
	Wed, 14 Jul 2010 14:25:52 -0400
8dd33d
From: Peter Jones <pjones@redhat.com>
8dd33d
To: Matt Domsch <Matt_Domsch@dell.com>
8dd33d
Cc: Peter Jones <pjones@redhat.com>, Stuart Hayes <stuart_hayes@dell.com>
8dd33d
Subject: [efibootmgr patch] Handle sector_size != 512.
8dd33d
Date: Wed, 14 Jul 2010 14:26:49 -0400
8dd33d
Message-Id: <1279132009-26635-1-git-send-email-pjones@redhat.com>
8dd33d
In-Reply-To: <1279121617-17961-1-git-send-email-pjones@redhat.com>
8dd33d
References: <1279121617-17961-1-git-send-email-pjones@redhat.com>
8dd33d
X-Scanned-By: MIMEDefang 2.67 on 10.5.11.21
8dd33d

8dd33d
Disks can have 4kB sectors now, so don't just bail out when that's the
8dd33d
case.
8dd33d
---
8dd33d
 src/include/disk.h |    3 +++
8dd33d
 src/lib/disk.c     |   43 +++++++++++++++++++++++++++++++++----------
8dd33d
 src/lib/gpt.c      |   30 ++++++++++++++----------------
8dd33d
 3 files changed, 50 insertions(+), 26 deletions(-)
8dd33d

8dd33d
diff --git a/src/include/disk.h b/src/include/disk.h
8dd33d
index eb93d10..8aa37d7 100644
8dd33d
--- a/src/include/disk.h
8dd33d
+++ b/src/include/disk.h
8dd33d
@@ -65,6 +65,9 @@ enum _interface_type {interface_type_unknown,
8dd33d
 		      ata, atapi, scsi, usb,
8dd33d
 		      i1394, fibre, i2o, md};
8dd33d
 
8dd33d
+
8dd33d
+unsigned int lcm(unsigned int x, unsigned int y);
8dd33d
+
8dd33d
 int disk_get_pci(int fd,
8dd33d
 		 unsigned char *bus,
8dd33d
 		 unsigned char *device,
8dd33d
diff --git a/src/lib/disk.c b/src/lib/disk.c
8dd33d
index 883864f..9c3a878 100644
8dd33d
--- a/src/lib/disk.c
8dd33d
+++ b/src/lib/disk.c
8dd33d
@@ -420,6 +420,27 @@ get_sector_size(int filedes)
8dd33d
 	return sector_size;
8dd33d
 }
8dd33d
 
8dd33d
+/************************************************************
8dd33d
+ * lcm
8dd33d
+ * Requires:
8dd33d
+ * - numbers of which to find the lowest common multiple
8dd33d
+ * Modifies: nothing
8dd33d
+ * Returns:
8dd33d
+ *  lowest common multiple of x and y
8dd33d
+ ************************************************************/
8dd33d
+unsigned int
8dd33d
+lcm(unsigned int x, unsigned int y)
8dd33d
+{
8dd33d
+	unsigned int m = x, n = y, o;
8dd33d
+
8dd33d
+	while ((o = m % n)) {
8dd33d
+		m = n;
8dd33d
+		n = o;
8dd33d
+	}
8dd33d
+
8dd33d
+	return (x / n) * y;
8dd33d
+}
8dd33d
+
8dd33d
 /**
8dd33d
  * disk_get_partition_info()
8dd33d
  *  @fd - open file descriptor to disk
8dd33d
@@ -442,26 +463,27 @@ disk_get_partition_info (int fd,
8dd33d
 			 uint8_t *mbr_type, uint8_t *signature_type)
8dd33d
 {
8dd33d
 	legacy_mbr *mbr;
8dd33d
-	void *mbr_unaligned;
8dd33d
+	void *mbr_sector;
8dd33d
+	size_t mbr_size;
8dd33d
 	off_t offset;
8dd33d
 	int this_bytes_read = 0;
8dd33d
 	int gpt_invalid=0, mbr_invalid=0;
8dd33d
 	int rc=0;
8dd33d
 	int sector_size = get_sector_size(fd);
8dd33d
 
8dd33d
-	if (sizeof(*mbr) != sector_size)
8dd33d
-		return 1;
8dd33d
-	mbr_unaligned = malloc(sizeof(*mbr)+sector_size-1);
8dd33d
-	mbr = (legacy_mbr *)
8dd33d
-		(((unsigned long)mbr_unaligned + sector_size - 1) &
8dd33d
-		 ~(unsigned long)(sector_size-1));
8dd33d
-	memset(mbr, 0, sizeof(*mbr));
8dd33d
+
8dd33d
+	mbr_size = lcm(sizeof(*mbr), sector_size);
8dd33d
+	if ((rc = posix_memalign(&mbr_sector, sector_size, mbr_size)) != 0)
8dd33d
+		goto error;
8dd33d
+	memset(mbr_sector, '\0', mbr_size);
8dd33d
+
8dd33d
 	offset = lseek(fd, 0, SEEK_SET);
8dd33d
-	this_bytes_read = read(fd, mbr, sizeof(*mbr));
8dd33d
+	this_bytes_read = read(fd, mbr_sector, mbr_size);
8dd33d
 	if (this_bytes_read < sizeof(*mbr)) {
8dd33d
 		rc=1;
8dd33d
 		goto error_free_mbr;
8dd33d
 	}
8dd33d
+	mbr = (legacy_mbr *)mbr_sector;
8dd33d
 	gpt_invalid = gpt_disk_get_partition_info(fd, num,
8dd33d
 						  start, size,
8dd33d
 						  signature,
8dd33d
@@ -479,7 +501,8 @@ disk_get_partition_info (int fd,
8dd33d
 		}
8dd33d
 	}
8dd33d
  error_free_mbr:
8dd33d
-	free(mbr_unaligned);
8dd33d
+	free(mbr_sector);
8dd33d
+ error:
8dd33d
 	return rc;
8dd33d
 }
8dd33d
 
8dd33d
diff --git a/src/lib/gpt.c b/src/lib/gpt.c
8dd33d
index d90ddaf..83e7a94 100644
8dd33d
--- a/src/lib/gpt.c
8dd33d
+++ b/src/lib/gpt.c
8dd33d
@@ -215,26 +215,24 @@ read_lastoddsector(int fd, uint64_t lba, void *buffer, size_t count)
8dd33d
 static ssize_t
8dd33d
 read_lba(int fd, uint64_t lba, void *buffer, size_t bytes)
8dd33d
 {
8dd33d
-	int sector_size = get_sector_size(fd);
8dd33d
-	off_t offset = lba * sector_size;
8dd33d
+        int sector_size = get_sector_size(fd);
8dd33d
+        off_t offset = lba * sector_size;
8dd33d
         ssize_t bytesread;
8dd33d
-        void *aligned;
8dd33d
-        void *unaligned;
8dd33d
-
8dd33d
-        if (bytes % sector_size)
8dd33d
-                return EINVAL;
8dd33d
+        void *iobuf;
8dd33d
+        size_t iobuf_size;
8dd33d
+        int rc;
8dd33d
 
8dd33d
-	unaligned = malloc(bytes+sector_size-1);
8dd33d
-	aligned = (void *)
8dd33d
-		(((unsigned long)unaligned + sector_size - 1) &
8dd33d
-		 ~(unsigned long)(sector_size-1));
8dd33d
-	memset(aligned, 0, bytes);
8dd33d
+        iobuf_size = lcm(bytes, sector_size);
8dd33d
+        rc = posix_memalign(&iobuf, sector_size, iobuf_size);
8dd33d
+        if (rc)
8dd33d
+                return rc;
8dd33d
+        memset(iobuf, 0, bytes);
8dd33d
 
8dd33d
 
8dd33d
-	lseek(fd, offset, SEEK_SET);
8dd33d
-	bytesread = read(fd, aligned, bytes);
8dd33d
-        memcpy(buffer, aligned, bytesread);
8dd33d
-        free(unaligned);
8dd33d
+        lseek(fd, offset, SEEK_SET);
8dd33d
+        bytesread = read(fd, iobuf, iobuf_size);
8dd33d
+        memcpy(buffer, iobuf, bytes);
8dd33d
+        free(iobuf);
8dd33d
 
8dd33d
         /* Kludge.  This is necessary to read/write the last
8dd33d
            block of an odd-sized disk, until Linux 2.5.x kernel fixes.
8dd33d
-- 
8dd33d
1.7.1.1
8dd33d