--- /dev/null
+Return-Path: pjones@redhat.com\r
+Received: from zmta02.collab.prod.int.phx2.redhat.com (LHLO\r
+ zmta02.collab.prod.int.phx2.redhat.com) (10.5.5.32) by\r
+ mail04.corp.redhat.com with LMTP; Wed, 14 Jul 2010 14:25:52 -0400 (EDT)\r
+Received: from localhost (localhost.localdomain [127.0.0.1])\r
+ by zmta02.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id B69C19F152\r
+ for <pjones@redhat.com>; Wed, 14 Jul 2010 14:25:52 -0400 (EDT)\r
+Received: from zmta02.collab.prod.int.phx2.redhat.com ([127.0.0.1])\r
+ by localhost (zmta02.collab.prod.int.phx2.redhat.com [127.0.0.1]) (amavisd-new, port 10024)\r
+ with ESMTP id jCHcGZehMQ5J for <pjones@redhat.com>;\r
+ Wed, 14 Jul 2010 14:25:52 -0400 (EDT)\r
+Received: from int-mx08.intmail.prod.int.phx2.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.21])\r
+ by zmta02.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id A601C9F14C\r
+ for <pjones@mail.corp.redhat.com>; Wed, 14 Jul 2010 14:25:52 -0400 (EDT)\r
+Received: from pjones4.install.bos.redhat.com (pjones4.install.bos.redhat.com [10.16.52.154])\r
+ by int-mx08.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o6EIPpGh017771;\r
+ Wed, 14 Jul 2010 14:25:52 -0400\r
+From: Peter Jones <pjones@redhat.com>\r
+To: Matt Domsch <Matt_Domsch@dell.com>\r
+Cc: Peter Jones <pjones@redhat.com>, Stuart Hayes <stuart_hayes@dell.com>\r
+Subject: [efibootmgr patch] Handle sector_size != 512.\r
+Date: Wed, 14 Jul 2010 14:26:49 -0400\r
+Message-Id: <1279132009-26635-1-git-send-email-pjones@redhat.com>\r
+In-Reply-To: <1279121617-17961-1-git-send-email-pjones@redhat.com>\r
+References: <1279121617-17961-1-git-send-email-pjones@redhat.com>\r
+X-Scanned-By: MIMEDefang 2.67 on 10.5.11.21\r
+\r
+Disks can have 4kB sectors now, so don't just bail out when that's the\r
+case.\r
+---\r
+ src/include/disk.h | 3 +++\r
+ src/lib/disk.c | 43 +++++++++++++++++++++++++++++++++----------\r
+ src/lib/gpt.c | 30 ++++++++++++++----------------\r
+ 3 files changed, 50 insertions(+), 26 deletions(-)\r
+\r
+diff --git a/src/include/disk.h b/src/include/disk.h\r
+index eb93d10..8aa37d7 100644\r
+--- a/src/include/disk.h\r
++++ b/src/include/disk.h\r
+@@ -65,6 +65,9 @@ enum _interface_type {interface_type_unknown,\r
+ ata, atapi, scsi, usb,\r
+ i1394, fibre, i2o, md};\r
+ \r
++\r
++unsigned int lcm(unsigned int x, unsigned int y);\r
++\r
+ int disk_get_pci(int fd,\r
+ unsigned char *bus,\r
+ unsigned char *device,\r
+diff --git a/src/lib/disk.c b/src/lib/disk.c\r
+index 883864f..9c3a878 100644\r
+--- a/src/lib/disk.c\r
++++ b/src/lib/disk.c\r
+@@ -420,6 +420,27 @@ get_sector_size(int filedes)\r
+ return sector_size;\r
+ }\r
+ \r
++/************************************************************\r
++ * lcm\r
++ * Requires:\r
++ * - numbers of which to find the lowest common multiple\r
++ * Modifies: nothing\r
++ * Returns:\r
++ * lowest common multiple of x and y\r
++ ************************************************************/\r
++unsigned int\r
++lcm(unsigned int x, unsigned int y)\r
++{\r
++ unsigned int m = x, n = y, o;\r
++\r
++ while ((o = m % n)) {\r
++ m = n;\r
++ n = o;\r
++ }\r
++\r
++ return (x / n) * y;\r
++}\r
++\r
+ /**\r
+ * disk_get_partition_info()\r
+ * @fd - open file descriptor to disk\r
+@@ -442,26 +463,27 @@ disk_get_partition_info (int fd,\r
+ uint8_t *mbr_type, uint8_t *signature_type)\r
+ {\r
+ legacy_mbr *mbr;\r
+- void *mbr_unaligned;\r
++ void *mbr_sector;\r
++ size_t mbr_size;\r
+ off_t offset;\r
+ int this_bytes_read = 0;\r
+ int gpt_invalid=0, mbr_invalid=0;\r
+ int rc=0;\r
+ int sector_size = get_sector_size(fd);\r
+ \r
+- if (sizeof(*mbr) != sector_size)\r
+- return 1;\r
+- mbr_unaligned = malloc(sizeof(*mbr)+sector_size-1);\r
+- mbr = (legacy_mbr *)\r
+- (((unsigned long)mbr_unaligned + sector_size - 1) &\r
+- ~(unsigned long)(sector_size-1));\r
+- memset(mbr, 0, sizeof(*mbr));\r
++\r
++ mbr_size = lcm(sizeof(*mbr), sector_size);\r
++ if ((rc = posix_memalign(&mbr_sector, sector_size, mbr_size)) != 0)\r
++ goto error;\r
++ memset(mbr_sector, '\0', mbr_size);\r
++\r
+ offset = lseek(fd, 0, SEEK_SET);\r
+- this_bytes_read = read(fd, mbr, sizeof(*mbr));\r
++ this_bytes_read = read(fd, mbr_sector, mbr_size);\r
+ if (this_bytes_read < sizeof(*mbr)) {\r
+ rc=1;\r
+ goto error_free_mbr;\r
+ }\r
++ mbr = (legacy_mbr *)mbr_sector;\r
+ gpt_invalid = gpt_disk_get_partition_info(fd, num,\r
+ start, size,\r
+ signature,\r
+@@ -479,7 +501,8 @@ disk_get_partition_info (int fd,\r
+ }\r
+ }\r
+ error_free_mbr:\r
+- free(mbr_unaligned);\r
++ free(mbr_sector);\r
++ error:\r
+ return rc;\r
+ }\r
+ \r
+diff --git a/src/lib/gpt.c b/src/lib/gpt.c\r
+index d90ddaf..83e7a94 100644\r
+--- a/src/lib/gpt.c\r
++++ b/src/lib/gpt.c\r
+@@ -215,26 +215,24 @@ read_lastoddsector(int fd, uint64_t lba, void *buffer, size_t count)\r
+ static ssize_t\r
+ read_lba(int fd, uint64_t lba, void *buffer, size_t bytes)\r
+ {\r
+- int sector_size = get_sector_size(fd);\r
+- off_t offset = lba * sector_size;\r
++ int sector_size = get_sector_size(fd);\r
++ off_t offset = lba * sector_size;\r
+ ssize_t bytesread;\r
+- void *aligned;\r
+- void *unaligned;\r
+-\r
+- if (bytes % sector_size)\r
+- return EINVAL;\r
++ void *iobuf;\r
++ size_t iobuf_size;\r
++ int rc;\r
+ \r
+- unaligned = malloc(bytes+sector_size-1);\r
+- aligned = (void *)\r
+- (((unsigned long)unaligned + sector_size - 1) &\r
+- ~(unsigned long)(sector_size-1));\r
+- memset(aligned, 0, bytes);\r
++ iobuf_size = lcm(bytes, sector_size);\r
++ rc = posix_memalign(&iobuf, sector_size, iobuf_size);\r
++ if (rc)\r
++ return rc;\r
++ memset(iobuf, 0, bytes);\r
+ \r
+ \r
+- lseek(fd, offset, SEEK_SET);\r
+- bytesread = read(fd, aligned, bytes);\r
+- memcpy(buffer, aligned, bytesread);\r
+- free(unaligned);\r
++ lseek(fd, offset, SEEK_SET);\r
++ bytesread = read(fd, iobuf, iobuf_size);\r
++ memcpy(buffer, iobuf, bytes);\r
++ free(iobuf);\r
+ \r
+ /* Kludge. This is necessary to read/write the last\r
+ block of an odd-sized disk, until Linux 2.5.x kernel fixes.\r
+-- \r
+1.7.1.1\r
+\r
return sector_size;
}
+/************************************************************
+ * lcm
+ * Requires:
+ * - numbers of which to find the lowest common multiple
+ * Modifies: nothing
+ * Returns:
+ * lowest common multiple of x and y
+ ************************************************************/
+unsigned int
+lcm(unsigned int x, unsigned int y)
+{
+ unsigned int m = x, n = y, o;
+
+ while ((o = m % n)) {
+ m = n;
+ n = o;
+ }
+
+ return (x / n) * y;
+}
+
/**
* disk_get_partition_info()
* @fd - open file descriptor to disk
uint8_t *mbr_type, uint8_t *signature_type)
{
legacy_mbr *mbr;
- void *mbr_unaligned;
+ void *mbr_sector;
+ size_t mbr_size;
off_t offset;
int this_bytes_read = 0;
int gpt_invalid=0, mbr_invalid=0;
int rc=0;
int sector_size = get_sector_size(fd);
- if (sizeof(*mbr) != sector_size)
- return 1;
- mbr_unaligned = malloc(sizeof(*mbr)+sector_size-1);
- mbr = (legacy_mbr *)
- (((unsigned long)mbr_unaligned + sector_size - 1) &
- ~(unsigned long)(sector_size-1));
- memset(mbr, 0, sizeof(*mbr));
+
+ mbr_size = lcm(sizeof(*mbr), sector_size);
+ if ((rc = posix_memalign(&mbr_sector, sector_size, mbr_size)) != 0)
+ goto error;
+ memset(mbr_sector, '\0', mbr_size);
+
offset = lseek(fd, 0, SEEK_SET);
- this_bytes_read = read(fd, mbr, sizeof(*mbr));
+ this_bytes_read = read(fd, mbr_sector, mbr_size);
if (this_bytes_read < sizeof(*mbr)) {
rc=1;
goto error_free_mbr;
}
+ mbr = (legacy_mbr *)mbr_sector;
gpt_invalid = gpt_disk_get_partition_info(fd, num,
start, size,
signature,
}
}
error_free_mbr:
- free(mbr_unaligned);
+ free(mbr_sector);
+ error:
return rc;
}
static ssize_t
read_lba(int fd, uint64_t lba, void *buffer, size_t bytes)
{
- int sector_size = get_sector_size(fd);
- off_t offset = lba * sector_size;
+ int sector_size = get_sector_size(fd);
+ off_t offset = lba * sector_size;
ssize_t bytesread;
- void *aligned;
- void *unaligned;
-
- if (bytes % sector_size)
- return EINVAL;
+ void *iobuf;
+ size_t iobuf_size;
+ int rc;
- unaligned = malloc(bytes+sector_size-1);
- aligned = (void *)
- (((unsigned long)unaligned + sector_size - 1) &
- ~(unsigned long)(sector_size-1));
- memset(aligned, 0, bytes);
+ iobuf_size = lcm(bytes, sector_size);
+ rc = posix_memalign(&iobuf, sector_size, iobuf_size);
+ if (rc)
+ return rc;
+ memset(iobuf, 0, bytes);
- lseek(fd, offset, SEEK_SET);
- bytesread = read(fd, aligned, bytes);
- memcpy(buffer, aligned, bytesread);
- free(unaligned);
+ lseek(fd, offset, SEEK_SET);
+ bytesread = read(fd, iobuf, iobuf_size);
+ memcpy(buffer, iobuf, bytes);
+ free(iobuf);
/* Kludge. This is necessary to read/write the last
block of an odd-sized disk, until Linux 2.5.x kernel fixes.