grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] Fix a special case when accessing partition on linux


From: Vladimir 'φ-coder/phcoder' Serbinenko
Subject: [PATCH] Fix a special case when accessing partition on linux
Date: Sun, 31 Jan 2010 21:00:56 +0100
User-agent: Mozilla-Thunderbird 2.0.0.22 (X11/20091109)

Because of cache coherency problem grub accesses partitions on linux by
hdaX device and not by hda with correct offset. The problem is that
because of 4K cache blocks disk.c may read sectors before the partition
and hence making hostdisk.c try to read from negative offset. I'm sad
that we need such workarounds for free systems.

-- 
Regards
Vladimir 'φ-coder/phcoder' Serbinenko

=== modified file 'util/hostdisk.c'
--- util/hostdisk.c     2010-01-25 17:04:22 +0000
+++ util/hostdisk.c     2010-01-31 11:52:27 +0000
@@ -336,7 +336,8 @@
     char dev[PATH_MAX];
 
     strcpy (dev, map[disk->id].device);
-    if (disk->partition && strncmp (map[disk->id].device, "/dev/", 5) == 0)
+    if (disk->partition && sector >= disk->partition->start
+       && strncmp (map[disk->id].device, "/dev/", 5) == 0)
       is_partition = linux_find_partition (dev, disk->partition->start);
 
     /* Open the partition.  */
@@ -490,6 +491,23 @@
 {
   int fd;
 
+  /* Split pre-partition and partition reads.  */
+  if (disk->partition && sector < disk->partition->start
+      && sector + size > disk->partition->start)
+    {
+      grub_err_t err;
+      err = grub_util_biosdisk_read (disk, sector,
+                                    disk->partition->start - sector,
+                                    buf);
+      if (err)
+       return err;
+
+      return grub_util_biosdisk_read (disk, disk->partition->start,
+                                     size - (disk->partition->start - sector),
+                                     buf + ((disk->partition->start - sector)
+                                            << GRUB_DISK_SECTOR_BITS));
+    }
+
   fd = open_device (disk, sector, O_RDONLY);
   if (fd < 0)
     return grub_errno;
@@ -527,6 +545,23 @@
 {
   int fd;
 
+  /* Split pre-partition and partition writes.  */
+  if (disk->partition && sector < disk->partition->start
+      && sector + size > disk->partition->start)
+    {
+      grub_err_t err;
+      err = grub_util_biosdisk_write (disk, sector,
+                                     disk->partition->start - sector,
+                                     buf);
+      if (err)
+       return err;
+
+      return grub_util_biosdisk_write (disk, disk->partition->start,
+                                      size - (disk->partition->start - sector),
+                                      buf + ((disk->partition->start - sector)
+                                             << GRUB_DISK_SECTOR_BITS));
+    }
+
   fd = open_device (disk, sector, O_WRONLY);
   if (fd < 0)
     return grub_errno;

Attachment: signature.asc
Description: OpenPGP digital signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]