[dm-devel] [PATCH 03/57] kpartx: parse emulated DASD devices

Hannes Reinecke hare at suse.de
Wed Apr 27 11:10:04 UTC 2016


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 <hare at 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




More information about the dm-devel mailing list