[kpartx] fix partition calculations of DASD partitions
authorroot <root@zezette.localdomain>
Mon, 11 Dec 2006 21:07:56 +0000 (22:07 +0100)
committerroot <root@zezette.localdomain>
Mon, 11 Dec 2006 21:07:56 +0000 (22:07 +0100)
This patch fixes the offset and length calcuations for DASD partitions
with either CMS (without explicit offset), the old linux disk layout or
no partition information at all if the devices are using a blocksize
bigger than 512B.
In the cases mentioned above the offset was normalized (to the number of
512B sectors) twice and the size reduced by the normalized offset and
again by the double normalized offset later.
This leads to kpartx defining the wrong limits in these cases.

Signed-off-by: Stefan Bader <shbader@de.ibm.com>
kpartx/dasd.c

index 69b9807..f31111f 100644 (file)
 #include "byteorder.h"
 #include "dasd.h"
 
+unsigned long sectors512(unsigned long sectors, int blocksize)
+{
+       return sectors * (blocksize >> 9);
+}
+
 /*
  */
 int 
 read_dasd_pt(int fd, struct slice all, struct slice *sp, int ns)
 {
        int retval = -1;
-       int blocksize, offset, size;
+       int blocksize;
        long disksize;
+       unsigned long offset, size;
        dasd_information_t info;
        struct hd_geometry geo;
        char type[5] = {0,};
@@ -172,13 +178,13 @@ read_dasd_pt(int fd, struct slice all, struct slice *sp, int ns)
                        /* disk is reserved minidisk */
                        blocksize = label[3];
                        offset = label[13];
-                       size = (label[7] - 1)*(blocksize >> 9);
+                       size   = sectors512(label[7] - 1, blocksize);
                } else {
-                       offset = (info.label_block + 1) * (blocksize >> 9);
-                       size = disksize - offset;
+                       offset = info.label_block + 1;
+                       size   = disksize;
                }
-               sp[0].start = offset * (blocksize >> 9);
-               sp[0].size = size - offset * (blocksize >> 9);
+               sp[0].start = sectors512(offset, blocksize);
+               sp[0].size  = size - sp[0].start;
                retval = 1;
        } else if ((strncmp(type, "VOL1", 4) == 0) &&
                (!info.FBA_layout) && (!strcmp(info.type, "ECKD"))) {
@@ -214,8 +220,8 @@ read_dasd_pt(int fd, struct slice all, struct slice *sp, int ns)
                        offset = cchh2blk(&f1.DS1EXT1.llimit, &geo);
                        size  = cchh2blk(&f1.DS1EXT1.ulimit, &geo) - 
                                offset + geo.sectors;
-                       sp[counter].start = offset * (blocksize >> 9);
-                       sp[counter].size = size * (blocksize >> 9);
+                       sp[counter].start = sectors512(offset, blocksize);
+                       sp[counter].size  = sectors512(size, blocksize);
                        counter++;
                        blk++;
                }
@@ -224,10 +230,8 @@ read_dasd_pt(int fd, struct slice all, struct slice *sp, int ns)
                /*
                 * Old style LNX1 or unlabeled disk
                 */
-               offset = (info.label_block + 1) * (blocksize >> 9);
-               size = disksize - offset;
-               sp[0].start = offset * (blocksize >> 9);
-               sp[0].size = size - offset * (blocksize >> 9);
+               sp[0].start = sectors512(info.label_block + 1, blocksize);
+               sp[0].size  = disksize - sp[0].start;
                retval = 1;
        }