Emulated DASD devices do not support the DASDINFO ioctl, so we need to generate the information by hand. After all, fdasd does the same.
Signed-off-by: Hannes Reinecke <h...@suse.de> --- kpartx/dasd.c | 39 +++++++++++++++++++++++++++++++++------ kpartx/dasd.h | 1 + 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/kpartx/dasd.c b/kpartx/dasd.c index 1fcf778..14c35b1 100644 --- a/kpartx/dasd.c +++ b/kpartx/dasd.c @@ -46,6 +46,21 @@ unsigned long long sectors512(unsigned long long sectors, int blocksize) return sectors * (blocksize >> 9); } +/* + * Magic records per track calculation, copied from fdasd.c + */ +static unsigned int ceil_quot(unsigned int d1, unsigned int d2) +{ + return (d1 + (d2 - 1)) / d2; +} + +unsigned int recs_per_track(unsigned int dl) +{ + int dn = ceil_quot(dl + 6, 232) + 1; + return 1729 / (10 + 9 + ceil_quot(dl + 6 * dn, 34)); +} + + typedef unsigned int __attribute__((__may_alias__)) label_ints_t; /* @@ -124,19 +139,31 @@ read_dasd_pt(int fd, struct slice all, struct slice *sp, int ns) } if (ioctl(fd_dasd, BIODASDINFO, (unsigned long)&info) != 0) { - goto out; + info.label_block = 2; + info.FBA_layout = 0; + memcpy(info.type, "ECKD", sizeof(info.type)); } - if (ioctl(fd_dasd, HDIO_GETGEO, (unsigned long)&geo) != 0) { + if (ioctl(fd_dasd, BLKSSZGET, &blocksize) != 0) goto out; - } if (ioctl(fd_dasd, BLKGETSIZE64, &disksize) != 0) goto out; - disksize >>= 9; - if (ioctl(fd_dasd, BLKSSZGET, &blocksize) != 0) - goto out; + if (ioctl(fd_dasd, HDIO_GETGEO, (unsigned long)&geo) != 0) { + unsigned int cyl; + + geo.heads = 15; + geo.sectors = recs_per_track(blocksize); + cyl = disksize / (blocksize * geo.heads * geo.sectors); + if (cyl < LV_COMPAT_CYL) + geo.cylinders = cyl; + else + geo.cylinders = LV_COMPAT_CYL; + geo.start = 0; + } + + disksize >>= 9; if (blocksize < 512 || blocksize > 4096) goto out; diff --git a/kpartx/dasd.h b/kpartx/dasd.h index 42f94db..6fa64e6 100644 --- a/kpartx/dasd.h +++ b/kpartx/dasd.h @@ -164,6 +164,7 @@ typedef struct dasd_information_t { #define BLKGETSIZE _IO(0x12,96) #define BLKSSZGET _IO(0x12,104) #define BLKGETSIZE64 _IOR(0x12,114,size_t) /* device size in bytes (u64 *arg)*/ +#define LV_COMPAT_CYL 0xFFFE /* * Only compile this on S/390. Doesn't make any sense -- 2.6.6 -- dm-devel mailing list dm-devel@redhat.com https://www.redhat.com/mailman/listinfo/dm-devel