multipath-tools: kpartx: fix partition calculations of DASD partitions 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 dasd.c | 28 ++++++++++++++++------------ 1 files changed, 16 insertions(+), 12 deletions(-) diff -Nurp multipath-tools-0.4.5.59/kpartx/dasd.c multipath-tools-0.4.5.59-kpartx/kpartx/dasd.c --- multipath-tools-0.4.5.59/kpartx/dasd.c 2006-12-07 12:52:21.000000000 +0100 +++ multipath-tools-0.4.5.59-kpartx/kpartx/dasd.c 2006-12-07 13:59:14.000000000 +0100 @@ -40,14 +40,20 @@ #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, s /* 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, s 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, s /* * 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; }