Skip to contentSkip to conversation

Fix a special case when accessing partition on linux

PATCH In review Vladimir 'φ-coder/phcoder' Serbinenko 2 participants 2 messages Jan 31, 2010

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 Fix a special case when accessing partition on linux

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.

Signature · 2 lines
Regards
Vladimir 'φ-coder/phcoder' Serbinenko

=== modified file 'util/hostdisk.c'

hostdisk.c +36 -1
@@ -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;
#1 lore raw
Quoted 5 lines · Vladimir 'φ-coder/phcoder' Serbinenko

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.

I would think it beneficial for long term code maintenance to put the above comments into the code itself.

// Because of a cache coherency problem grub accesses partitions // on linux by an hdaX device and not by hda with the correct offset. // The problem is that because of 4K cache blocks, disk.c may // read sectors before the partition and hence make
// hostdisk.c try to read from a negative offset.

-- Bruce