[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[lvm-devel] [PATCH] lvm2 support for detecting v1.x MD superblocks



lvm2's MD v1.0 superblock detection doesn't work at all (because it
doesn't use v1 sb offsets).

I've tested the attached patch to work on MDs with v0.90.0, v1.0,
v1.1, and v1.2 superblocks.

please advise, thanks.
Mike
Index: lib/device/dev-md.c
===================================================================
RCS file: /cvs/lvm2/LVM2/lib/device/dev-md.c,v
retrieving revision 1.5
diff -u -r1.5 dev-md.c
--- lib/device/dev-md.c	20 Aug 2007 20:55:25 -0000	1.5
+++ lib/device/dev-md.c	23 Oct 2007 15:17:57 -0000
@@ -25,6 +25,40 @@
 #define MD_NEW_SIZE_SECTORS(x) ((x & ~(MD_RESERVED_SECTORS - 1)) \
 				- MD_RESERVED_SECTORS)
 
+int dev_has_md_sb(struct device *dev, uint64_t sb_offset, uint64_t *sb)
+{
+	int ret = 0;	
+	uint32_t md_magic;
+	/* Version 1 is little endian; version 0.90.0 is machine endian */
+	if (dev_read(dev, sb_offset, sizeof(uint32_t), &md_magic) &&
+	    ((md_magic == xlate32(MD_SB_MAGIC)) ||
+	     (md_magic == MD_SB_MAGIC))) {
+		if (sb)
+			*sb = sb_offset;
+		ret = 1;
+	}
+	return ret;
+}
+
+uint64_t v1_sb_offset(uint64_t size, int minor_version) {
+	uint64_t sb_offset;
+	switch(minor_version) {
+	case 0:
+		sb_offset = size;
+		sb_offset -= 8*2;
+		sb_offset &= ~(4*2-1);
+		break;
+	case 1:
+		sb_offset = 0;
+		break;
+	case 2:
+		sb_offset = 4*2;
+		break;
+	}
+	sb_offset <<= SECTOR_SHIFT;
+	return sb_offset;
+}
+
 /*
  * Returns -1 on error
  */
@@ -35,7 +69,6 @@
 #ifdef linux
 
 	uint64_t size, sb_offset;
-	uint32_t md_magic;
 
 	if (!dev_get_size(dev, &size)) {
 		stack;
@@ -50,16 +83,20 @@
 		return -1;
 	}
 
-	sb_offset = MD_NEW_SIZE_SECTORS(size) << SECTOR_SHIFT;
-
 	/* Check if it is an md component device. */
-	/* Version 1 is little endian; version 0.90.0 is machine endian */
-	if (dev_read(dev, sb_offset, sizeof(uint32_t), &md_magic) &&
-	    ((md_magic == xlate32(MD_SB_MAGIC)) ||
-	     (md_magic == MD_SB_MAGIC))) {
-		if (sb)
-			*sb = sb_offset;
+	/* Version 0.90.0 */
+	sb_offset = MD_NEW_SIZE_SECTORS(size) << SECTOR_SHIFT;
+	if (dev_has_md_sb(dev, sb_offset, sb)) {
 		ret = 1;
+	} else {
+		/* Version 1, try v1.0 -> v1.2 */
+		int minor;
+		for (minor = 0; minor <= 2; minor++) {
+			if (dev_has_md_sb(dev, v1_sb_offset(size, minor), sb)) {
+				ret = 1;
+				break;
+			}
+		}
 	}
 
 	if (!dev_close(dev))

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]