summaryrefslogtreecommitdiff
path: root/sys-boot/grub/files/ubuntu-upstream-1.98/968_hostdisk_speedup.diff
diff options
context:
space:
mode:
Diffstat (limited to 'sys-boot/grub/files/ubuntu-upstream-1.98/968_hostdisk_speedup.diff')
-rw-r--r--sys-boot/grub/files/ubuntu-upstream-1.98/968_hostdisk_speedup.diff310
1 files changed, 310 insertions, 0 deletions
diff --git a/sys-boot/grub/files/ubuntu-upstream-1.98/968_hostdisk_speedup.diff b/sys-boot/grub/files/ubuntu-upstream-1.98/968_hostdisk_speedup.diff
new file mode 100644
index 00000000..30ebcbea
--- /dev/null
+++ b/sys-boot/grub/files/ubuntu-upstream-1.98/968_hostdisk_speedup.diff
@@ -0,0 +1,310 @@
+Upstream: http://lists.gnu.org/archive/html/grub-devel/2010-03/msg00008.html
+Description: Optimise hostdisk device handling
+ This substantially speeds up grub-probe filesystem reads.
+
+diff -Nur -x '*.orig' -x '*~' grub2/ChangeLog.hostdisk-speedup grub2.new/ChangeLog.hostdisk-speedup
+--- grub2/ChangeLog.hostdisk-speedup 1970-01-01 01:00:00.000000000 +0100
++++ grub2.new/ChangeLog.hostdisk-speedup 2010-03-03 10:43:43.000000000 +0000
+@@ -0,0 +1,18 @@
++2010-03-03 Colin Watson <cjwatson@ubuntu.com>
++
++ * util/hostdisk.c (struct grub_util_biosdisk_data): New structure.
++ (grub_util_biosdisk_open): Initialise disk->data.
++ (struct linux_partition_cache): New structure.
++ (linux_find_partition): Cache partition start positions; these are
++ expensive to compute on every read and write.
++ (open_device): Cache open file descriptor in disk->data, so that we
++ don't have to reopen it and flush the buffer cache for consecutive
++ operations on the same device.
++ (grub_util_biosdisk_close): New function.
++ (grub_util_biosdisk_dev): Set `close' member.
++
++ * conf/common.rmk (grub_probe_SOURCES): Add kern/list.c.
++ * conf/i386-efi.rmk (grub_setup_SOURCES): Likewise.
++ * conf/i386-pc.rmk (grub_setup_SOURCES): Likewise.
++ * conf/sparc64-ieee1275.rmk (grub_setup_SOURCES): Likewise.
++ * conf/x86_64-efi.rmk (grub_setup_SOURCES): Likewise.
+diff -Nur -x '*.orig' -x '*~' grub2/conf/common.rmk grub2.new/conf/common.rmk
+--- grub2/conf/common.rmk 2010-03-03 20:11:04.000000000 +0000
++++ grub2.new/conf/common.rmk 2010-03-03 20:11:05.000000000 +0000
+@@ -25,7 +25,7 @@
+ grub_probe_SOURCES = gnulib/progname.c util/grub-probe.c \
+ util/hostdisk.c util/misc.c util/getroot.c \
+ kern/device.c kern/disk.c kern/err.c kern/misc.c \
+- kern/parser.c kern/partition.c kern/file.c \
++ kern/parser.c kern/partition.c kern/file.c kern/list.c \
+ \
+ fs/affs.c fs/cpio.c fs/fat.c fs/ext2.c fs/hfs.c \
+ fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \
+diff -Nur -x '*.orig' -x '*~' grub2/conf/i386-efi.rmk grub2.new/conf/i386-efi.rmk
+--- grub2/conf/i386-efi.rmk 2010-03-03 20:08:04.000000000 +0000
++++ grub2.new/conf/i386-efi.rmk 2010-03-03 20:11:05.000000000 +0000
+@@ -21,7 +21,7 @@
+ # kern/err.c kern/misc.c fs/fat.c fs/ext2.c fs/xfs.c fs/affs.c \
+ # fs/sfs.c kern/parser.c kern/partition.c partmap/msdos.c \
+ # fs/ufs.c fs/ufs2.c fs/minix.c fs/hfs.c fs/jfs.c fs/hfsplus.c kern/file.c \
+-# kern/fs.c kern/env.c fs/fshelp.c
++# kern/fs.c kern/env.c kern/list.c fs/fshelp.c
+
+ # Scripts.
+ sbin_SCRIPTS = grub-install
+diff -Nur -x '*.orig' -x '*~' grub2/conf/i386-pc.rmk grub2.new/conf/i386-pc.rmk
+--- grub2/conf/i386-pc.rmk 2010-03-03 20:08:04.000000000 +0000
++++ grub2.new/conf/i386-pc.rmk 2010-03-03 20:11:05.000000000 +0000
+@@ -96,7 +96,8 @@
+ util/i386/pc/grub-setup.c util/hostdisk.c \
+ util/misc.c util/getroot.c kern/device.c kern/disk.c \
+ kern/err.c kern/misc.c kern/parser.c kern/partition.c \
+- kern/file.c kern/fs.c kern/env.c fs/fshelp.c \
++ kern/file.c kern/fs.c kern/env.c kern/list.c \
++ fs/fshelp.c \
+ \
+ fs/affs.c fs/cpio.c fs/ext2.c fs/fat.c fs/hfs.c \
+ fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \
+diff -Nur -x '*.orig' -x '*~' grub2/conf/sparc64-ieee1275.rmk grub2.new/conf/sparc64-ieee1275.rmk
+--- grub2/conf/sparc64-ieee1275.rmk 2010-03-03 20:08:04.000000000 +0000
++++ grub2.new/conf/sparc64-ieee1275.rmk 2010-03-03 20:11:05.000000000 +0000
+@@ -70,7 +70,8 @@
+ grub_setup_SOURCES = util/sparc64/ieee1275/grub-setup.c util/hostdisk.c \
+ util/misc.c util/getroot.c kern/device.c kern/disk.c \
+ kern/err.c kern/misc.c kern/parser.c kern/partition.c \
+- kern/file.c kern/fs.c kern/env.c fs/fshelp.c \
++ kern/file.c kern/fs.c kern/env.c kern/list.c \
++ fs/fshelp.c \
+ \
+ fs/affs.c fs/cpio.c fs/ext2.c fs/fat.c fs/hfs.c \
+ fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \
+diff -Nur -x '*.orig' -x '*~' grub2/conf/x86_64-efi.rmk grub2.new/conf/x86_64-efi.rmk
+--- grub2/conf/x86_64-efi.rmk 2010-03-03 20:08:04.000000000 +0000
++++ grub2.new/conf/x86_64-efi.rmk 2010-03-03 20:11:05.000000000 +0000
+@@ -20,7 +20,7 @@
+ # kern/err.c kern/misc.c fs/fat.c fs/ext2.c fs/xfs.c fs/affs.c \
+ # fs/sfs.c kern/parser.c kern/partition.c partmap/msdos.c \
+ # fs/ufs.c fs/ufs2.c fs/minix.c fs/hfs.c fs/jfs.c fs/hfsplus.c kern/file.c \
+-# kern/fs.c kern/env.c fs/fshelp.c
++# kern/fs.c kern/env.c kern/list.c fs/fshelp.c
+
+ # Scripts.
+ sbin_SCRIPTS = grub-install
+diff -Nur -x '*.orig' -x '*~' grub2/util/hostdisk.c grub2.new/util/hostdisk.c
+--- grub2/util/hostdisk.c 2010-03-03 20:11:04.000000000 +0000
++++ grub2.new/util/hostdisk.c 2010-03-03 20:11:05.000000000 +0000
+@@ -26,6 +26,7 @@
+ #include <grub/util/hostdisk.h>
+ #include <grub/misc.h>
+ #include <grub/i18n.h>
++#include <grub/list.h>
+
+ #include <stdio.h>
+ #include <stdlib.h>
+@@ -107,6 +108,13 @@
+ char *device;
+ } map[256];
+
++struct grub_util_biosdisk_data
++{
++ char *dev;
++ int access_mode;
++ int fd;
++};
++
+ #ifdef __linux__
+ /* Check if we have devfs support. */
+ static int
+@@ -169,6 +177,7 @@
+ {
+ int drive;
+ struct stat st;
++ struct grub_util_biosdisk_data *data;
+
+ drive = find_grub_drive (name);
+ if (drive < 0)
+@@ -177,6 +186,10 @@
+
+ disk->has_partitions = 1;
+ disk->id = drive;
++ disk->data = data = xmalloc (sizeof (struct grub_util_biosdisk_data));
++ data->dev = NULL;
++ data->access_mode = 0;
++ data->fd = -1;
+
+ /* Get the size. */
+ #if defined(__MINGW32__)
+@@ -367,6 +380,17 @@
+ #endif /* __linux__ || __CYGWIN__ */
+
+ #ifdef __linux__
++/* Cache of partition start sectors for each disk. */
++struct linux_partition_cache
++{
++ struct linux_partition_cache *next;
++ char *dev;
++ unsigned long start;
++ int partno;
++};
++
++struct linux_partition_cache *linux_partition_cache_list;
++
+ static int
+ linux_find_partition (char *dev, unsigned long sector)
+ {
+@@ -375,6 +399,7 @@
+ char *p;
+ int i;
+ char real_dev[PATH_MAX];
++ struct linux_partition_cache *cache;
+
+ strcpy(real_dev, dev);
+
+@@ -394,6 +419,16 @@
+ format = "%d";
+ }
+
++ for (cache = linux_partition_cache_list; cache; cache = cache->next)
++ {
++ if (strcmp (cache->dev, dev) == 0 && cache->start == sector)
++ {
++ sprintf (p, format, cache->partno);
++ strcpy (dev, real_dev);
++ return 1;
++ }
++ }
++
+ for (i = 1; i < 10000; i++)
+ {
+ int fd;
+@@ -412,6 +447,15 @@
+
+ if (start == sector)
+ {
++ struct linux_partition_cache *new_cache_item;
++
++ new_cache_item = xmalloc (sizeof *new_cache_item);
++ new_cache_item->dev = xstrdup (dev);
++ new_cache_item->start = start;
++ new_cache_item->partno = i;
++ grub_list_push (GRUB_AS_LIST_P (&linux_partition_cache_list),
++ GRUB_AS_LIST (new_cache_item));
++
+ strcpy (dev, real_dev);
+ return 1;
+ }
+@@ -425,6 +469,7 @@
+ open_device (const grub_disk_t disk, grub_disk_addr_t sector, int flags)
+ {
+ int fd;
++ struct grub_util_biosdisk_data *data = disk->data;
+
+ #ifdef O_LARGEFILE
+ flags |= O_LARGEFILE;
+@@ -451,18 +496,35 @@
+ && strncmp (map[disk->id].device, "/dev/", 5) == 0)
+ is_partition = linux_find_partition (dev, disk->partition->start);
+
+- /* Open the partition. */
+- grub_dprintf ("hostdisk", "opening the device `%s' in open_device()\n", dev);
+- fd = open (dev, flags);
+- if (fd < 0)
++ if (data->dev && strcmp (data->dev, dev) == 0 &&
++ data->access_mode == (flags & O_ACCMODE))
+ {
+- grub_error (GRUB_ERR_BAD_DEVICE, "cannot open `%s'", dev);
+- return -1;
++ grub_dprintf ("hostdisk", "reusing open device `%s'\n", dev);
++ fd = data->fd;
+ }
++ else
++ {
++ free (data->dev);
++ if (data->fd != -1)
++ close (data->fd);
++
++ /* Open the partition. */
++ grub_dprintf ("hostdisk", "opening the device `%s' in open_device()\n", dev);
++ fd = open (dev, flags);
++ if (fd < 0)
++ {
++ grub_error (GRUB_ERR_BAD_DEVICE, "cannot open `%s'", dev);
++ return -1;
++ }
+
+- /* Flush the buffer cache to the physical disk.
+- XXX: This also empties the buffer cache. */
+- ioctl (fd, BLKFLSBUF, 0);
++ /* Flush the buffer cache to the physical disk.
++ XXX: This also empties the buffer cache. */
++ ioctl (fd, BLKFLSBUF, 0);
++
++ data->dev = xstrdup (dev);
++ data->access_mode = (flags & O_ACCMODE);
++ data->fd = fd;
++ }
+
+ if (is_partition)
+ sector -= disk->partition->start;
+@@ -486,7 +548,26 @@
+ }
+ #endif
+
+- fd = open (map[disk->id].device, flags);
++ if (data->dev && strcmp (data->dev, map[disk->id].device) == 0 &&
++ data->access_mode == (flags & O_ACCMODE))
++ {
++ grub_dprintf ("hostdisk", "reusing open device `%s'\n", data->dev);
++ fd = data->fd;
++ }
++ else
++ {
++ free (data->dev);
++ if (data->fd != -1)
++ close (data->fd);
++
++ fd = open (map[disk->id].device, flags);
++ if (fd >= 0)
++ {
++ data->dev = xstrdup (map[disk->id].device);
++ data->access_mode = (flags & O_ACCMODE);
++ data->fd = fd;
++ }
++ }
+
+ #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+ if (! (sysctl_oldflags & 0x10)
+@@ -646,7 +727,6 @@
+ != (ssize_t) (size << GRUB_DISK_SECTOR_BITS))
+ grub_error (GRUB_ERR_READ_ERROR, "cannot read from `%s'", map[disk->id].device);
+
+- close (fd);
+ return grub_errno;
+ }
+
+@@ -681,17 +761,27 @@
+ != (ssize_t) (size << GRUB_DISK_SECTOR_BITS))
+ grub_error (GRUB_ERR_WRITE_ERROR, "cannot write to `%s'", map[disk->id].device);
+
+- close (fd);
+ return grub_errno;
+ }
+
++static void
++grub_util_biosdisk_close (struct grub_disk *disk)
++{
++ struct grub_util_biosdisk_data *data = disk->data;
++
++ free (data->dev);
++ if (data->fd != -1)
++ close (data->fd);
++ free (data);
++}
++
+ static struct grub_disk_dev grub_util_biosdisk_dev =
+ {
+ .name = "biosdisk",
+ .id = GRUB_DISK_DEVICE_BIOSDISK_ID,
+ .iterate = grub_util_biosdisk_iterate,
+ .open = grub_util_biosdisk_open,
+- .close = 0,
++ .close = grub_util_biosdisk_close,
+ .read = grub_util_biosdisk_read,
+ .write = grub_util_biosdisk_write,
+ .next = 0