bitkeeper revision 1.430.1.1 (3f696aa1CyubWLx68ZHs_WKjwBKnDA)
authorkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Thu, 18 Sep 2003 08:19:45 +0000 (08:19 +0000)
committerkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Thu, 18 Sep 2003 08:19:45 +0000 (08:19 +0000)
xeno.c:
  Fix partition table reading when a guest is granted full access to a physical block device.

xenolinux-2.4.22-sparse/fs/partitions/xeno.c

index ef48583eb9ad3f8a45e003617fd672c22b669a2b..98cd08d65af6e51d6cb3366dd27906c53f4183b9 100644 (file)
@@ -1,5 +1,4 @@
-/* Simple hack so that client XenoLinux's can sort-of see parts of the
-   host partition table. */
+
 #include <linux/kernel.h>
 #include <asm/hypervisor.h>
 #include <linux/fs.h>
@@ -17,9 +16,9 @@ extern unsigned short xldev_to_physdev(kdev_t xldev);
 
 /* Grab the physdisk partitions list from the hypervisor. */
 int xeno_partition(struct gendisk *hd,
-                  struct block_device *bdev,
-                  unsigned long first_sec,
-                  int first_part_minor)
+                   struct block_device *bdev,
+                   unsigned long first_sec,
+                   int first_part_minor)
 {
     physdisk_probebuf_t *buf;
     int i, minor;
@@ -46,29 +45,39 @@ int xeno_partition(struct gendisk *hd,
     buf->n_aces = PHYSDISK_MAX_ACES_PER_REQUEST;
 
     xenolinux_control_msg(XEN_BLOCK_PHYSDEV_PROBE, (char *)buf,
-                         sizeof(*buf));
+                          sizeof(*buf));
 
     if ( buf->n_aces == PHYSDISK_MAX_ACES_PER_REQUEST )
         printk(KERN_ALERT "Too many returns for xeno partition parser\n");
 
+    /* Check for access to whole disk, allowing direct p.t. access. */
+    for ( i = 0; i < buf->n_aces; i++ )
+    {
+        if ( (buf->entries[i].device == xldev_to_physdev(bdev->bd_dev)) &&
+             (buf->entries[i].partition == 0) )
+        {
+            kfree(buf);
+            return 0;
+        }
+    }
+
+    /* No direct access so trawl through the access lists instead. */
     for ( i = 0; i < buf->n_aces; i++ )
     {
-        if (buf->entries[i].partition == 0)
-           continue;
-       if (buf->entries[i].device != xldev_to_physdev(bdev->bd_dev))
-           continue;
+        if (buf->entries[i].device != xldev_to_physdev(bdev->bd_dev))
+            continue;
         if (!(buf->entries[i].mode & PHYSDISK_MODE_W))
         {
             if (!(buf->entries[i].mode & PHYSDISK_MODE_R))
                 continue;
             set_device_ro(bdev->bd_dev, 1);
         }
-       minor = buf->entries[i].partition + first_part_minor - 1;
-       add_gd_partition(hd,
-                        minor,
-                        buf->entries[i].start_sect,
-                        buf->entries[i].n_sectors);
-    }  
+        minor = buf->entries[i].partition + first_part_minor - 1;
+        add_gd_partition(hd,
+                         minor,
+                         buf->entries[i].start_sect,
+                         buf->entries[i].n_sectors);
+    }
 
     kfree(buf);