Ok, I noticed that there were some mistakes that partition numbers
are not properly masked in several functions in block.c.

EXCUSE: the code was not written by me. :p

So, here is a patch. Can you test this?

Okuji


Index: linux/dev/glue/block.c
===================================================================
RCS file: /home/cvs/gnumach/linux/dev/glue/block.c,v
retrieving revision 1.3
diff -u -r1.3 block.c
--- linux/dev/glue/block.c      1999/06/27 23:51:47     1.3
+++ linux/dev/glue/block.c      2000/08/15 23:36:05
@@ -531,7 +531,9 @@
   for (gd = gendisk_head, nsect = -1; gd; gd = gd->next)
     if (gd->major == MAJOR (dev))
       {
-       nsect = gd->part[MINOR (dev)].nr_sects;
+       unsigned mask = (1 << gd->minor_shift) - 1;
+
+       nsect = gd->part[MINOR (dev) & mask].nr_sects;
        break;
       }
   if (nsect > 0)
@@ -935,7 +937,8 @@
   struct gendisk *gd = ds->gd;
   struct partition *p;
   struct temp_data *d = current_thread ()->pcb->data;
-
+  unsigned mask = (1 << gd->minor_shift) - 1;
+  
   if (! gd)
     {
       *part = -1;
@@ -951,9 +954,12 @@
          sizeof (struct disklabel *) * gd->max_nr * gd->max_p);
   for (i = 1; i < gd->max_p; i++)
     {
+      unsigned part;
+      
       d->inode.i_rdev = *dev | i;
-      if (gd->part[MINOR (d->inode.i_rdev)].nr_sects <= 0
-         || gd->part[MINOR (d->inode.i_rdev)].start_sect < 0)
+      part = MINOR (d->inode.i_rdev) & mask;
+      if (gd->part[part].nr_sects <= 0
+         || gd->part[part].start_sect < 0)
        continue;
       linux_intr_pri = SPL5;
       d->file.f_flags = 0;
@@ -975,11 +981,11 @@
                continue;
 
              /* Sanity check.  */
-             if (p->p_size > gd->part[MINOR (d->inode.i_rdev)].nr_sects)
-               p->p_size = gd->part[MINOR (d->inode.i_rdev)].nr_sects;
+             if (p->p_size > gd->part[part].nr_sects)
+               p->p_size = gd->part[part].nr_sects;
            }
        }
-      ds->labels[MINOR (d->inode.i_rdev)] = lp;
+      ds->labels[part] = lp;
     }
 
 check:
@@ -989,8 +995,8 @@
     return D_NO_SUCH_DEVICE;
   *dev = MKDEV (MAJOR (*dev), MINOR (*dev) | slice);
   if (slice >= gd->max_p
-      || gd->part[MINOR (*dev)].start_sect < 0
-      || gd->part[MINOR (*dev)].nr_sects <= 0)
+      || gd->part[MINOR (*dev) & mask].start_sect < 0
+      || gd->part[MINOR (*dev) & mask].nr_sects <= 0)
     return D_NO_SUCH_DEVICE;
   if (*part >= 0)
     {
@@ -1264,7 +1270,8 @@
   int major, minor;
   long maxsz, sz;
   struct disklabel *lp = NULL;
-
+  unsigned mask;
+  
   if (count <= 0)
     return count;
 
@@ -1273,6 +1280,8 @@
 
   if (bd->ds->gd)
     {
+      mask = (1 << bd->ds->gd->minor_shift) - 1;
+      
       if (bd->part >= 0)
        {
          assert (bd->ds->labels);
@@ -1281,7 +1290,7 @@
          maxsz = lp->d_partitions[bd->part].p_size;
        }
       else
-       maxsz = bd->ds->gd->part[minor].nr_sects;
+       maxsz = bd->ds->gd->part[minor & mask].nr_sects;
     }
   else
     {
@@ -1296,7 +1305,7 @@
     count = sz << 9;
   if (lp)
     bn += (lp->d_partitions[bd->part].p_offset
-          - bd->ds->gd->part[minor].start_sect);
+          - bd->ds->gd->part[minor & mask].start_sect);
   *off = (loff_t) bn << 9;
   bd->iocount++;
   return count;
@@ -1610,8 +1619,12 @@
               = lp->d_partitions[bd->part].p_size << 9);
            }
          else
-           (status[DEV_GET_SIZE_DEVICE_SIZE]
-            = bd->ds->gd->part[MINOR (bd->dev)].nr_sects << 9);
+           {
+             unsigned mask = (1 << bd->ds->gd->minor_shift) - 1;
+             
+             (status[DEV_GET_SIZE_DEVICE_SIZE]
+              = bd->ds->gd->part[MINOR (bd->dev) & mask].nr_sects << 9);
+           }
        }
       else
        {

Reply via email to