NeilBrown: Handle negative delta_disks in super0 and super1.

Martin F. Krafft madduck at alioth.debian.org
Wed Jan 27 02:02:00 UTC 2010


Module: mdadm
Branch: master
Commit: 4180aa4d4e73eea810d51604e6e558a973cf1979
URL:    http://git.debian.org/?p=pkg-mdadm/mdadm.git;a=commit;h=4180aa4d4e73eea810d51604e6e558a973cf1979

Author: NeilBrown <neilb at suse.de>
Date:   Fri Oct 16 17:43:54 2009 +1100

Handle negative delta_disks in super0 and super1.

Signed-off-by: NeilBrown <neilb at suse.de>

---

 super0.c |   12 +++++++-----
 super1.c |   23 ++++++++++++-----------
 2 files changed, 19 insertions(+), 16 deletions(-)

diff --git a/super0.c b/super0.c
index b84db29..69fb460 100644
--- a/super0.c
+++ b/super0.c
@@ -85,6 +85,7 @@ static void examine_super0(struct supertype *st, char *homehost)
 	mdp_super_t *sb = st->sb;
 	time_t atime;
 	int d;
+	int delta_extra = 0;
 	char *c;
 
 	printf("          Magic : %08x\n", sb->md_magic);
@@ -135,10 +136,9 @@ static void examine_super0(struct supertype *st, char *homehost)
 		printf("  Reshape pos'n : %llu%s\n", (unsigned long long)sb->reshape_position/2, human_size((long long)sb->reshape_position<<9));
 		if (sb->delta_disks) {
 			printf("  Delta Devices : %d", sb->delta_disks);
-			if (sb->delta_disks > 0)
-				printf(" (%d->%d)\n", sb->raid_disks-sb->delta_disks, sb->raid_disks);
-			else
-				printf(" (%d->%d)\n", sb->raid_disks, sb->raid_disks+sb->delta_disks);
+			printf(" (%d->%d)\n", sb->raid_disks-sb->delta_disks, sb->raid_disks);
+			if (((int)sb->delta_disks) < 0)
+				delta_extra = - sb->delta_disks;
 		}
 		if (sb->new_level != sb->level) {
 			c = map_num(pers, sb->new_level);
@@ -210,7 +210,7 @@ static void examine_super0(struct supertype *st, char *homehost)
 	}
 	printf("\n");
 	printf("      Number   Major   Minor   RaidDevice State\n");
-	for (d= -1; d<(signed int)(sb->raid_disks+sb->spare_disks); d++) {
+	for (d= -1; d<(signed int)(sb->raid_disks+delta_extra + sb->spare_disks); d++) {
 		mdp_disk_t *dp;
 		char *dv;
 		char nb[5];
@@ -379,6 +379,8 @@ static void getinfo_super0(struct supertype *st, struct mdinfo *info)
 		info->delta_disks = sb->delta_disks;
 		info->new_layout = sb->new_layout;
 		info->new_chunk = sb->new_chunk;
+		if (info->delta_disks < 0)
+			info->array.raid_disks -= info->delta_disks;
 	} else
 		info->reshape_active = 0;
 
diff --git a/super1.c b/super1.c
index 540c776..a64876e 100644
--- a/super1.c
+++ b/super1.c
@@ -76,8 +76,8 @@ struct mdp_superblock_1 {
 	__u64	utime;		/* 40 bits second, 24 btes microseconds */
 	__u64	events;		/* incremented when superblock updated */
 	__u64	resync_offset;	/* data before this offset (from data_offset) known to be in sync */
-	__u32	sb_csum;	/* checksum upto devs[max_dev] */
-	__u32	max_dev;	/* size of devs[] array to consider */
+	__u32	sb_csum;	/* checksum upto dev_roles[max_dev] */
+	__u32	max_dev;	/* size of dev_roles[] array to consider */
 	__u8	pad3[64-32];	/* set to 0 when writing */
 
 	/* device state information. Indexed by dev_number.
@@ -201,6 +201,7 @@ static void examine_super1(struct supertype *st, char *homehost)
 	time_t atime;
 	int d;
 	int role;
+	int delta_extra = 0;
 	int i;
 	char *c;
 	int l = homehost ? strlen(homehost) : 0;
@@ -283,13 +284,11 @@ static void examine_super1(struct supertype *st, char *homehost)
 		       human_size(__le64_to_cpu(sb->reshape_position)<<9));
 		if (__le32_to_cpu(sb->delta_disks)) {
 			printf("  Delta Devices : %d", __le32_to_cpu(sb->delta_disks));
-			if (__le32_to_cpu(sb->delta_disks))
-				printf(" (%d->%d)\n",
-				       __le32_to_cpu(sb->raid_disks)-__le32_to_cpu(sb->delta_disks),
-				       __le32_to_cpu(sb->raid_disks));
-			else
-				printf(" (%d->%d)\n", __le32_to_cpu(sb->raid_disks),
-				       __le32_to_cpu(sb->raid_disks)+__le32_to_cpu(sb->delta_disks));
+			printf(" (%d->%d)\n",
+			       __le32_to_cpu(sb->raid_disks)-__le32_to_cpu(sb->delta_disks),
+			       __le32_to_cpu(sb->raid_disks));
+			if ((int)__le32_to_cpu(sb->delta_disks) < 0)
+				delta_extra = -__le32_to_cpu(sb->delta_disks);
 		}
 		if (__le32_to_cpu(sb->new_level) != __le32_to_cpu(sb->level)) {
 			c = map_num(pers, __le32_to_cpu(sb->new_level));
@@ -376,7 +375,7 @@ static void examine_super1(struct supertype *st, char *homehost)
 #endif
 	printf("   Device Role : ");
 	d = __le32_to_cpu(sb->dev_number);
-	if (d < sb->raid_disks)
+	if (d < __le32_to_cpu(sb->max_dev))
 		role = __le16_to_cpu(sb->dev_roles[d]);
 	else
 		role = 0xFFFF;
@@ -386,7 +385,7 @@ static void examine_super1(struct supertype *st, char *homehost)
 		printf("Active device %d\n", role);
 
 	printf("   Array State : ");
-	for (d=0; d<__le32_to_cpu(sb->raid_disks); d++) {
+	for (d=0; d<__le32_to_cpu(sb->raid_disks) + delta_extra; d++) {
 		int cnt = 0;
 		int me = 0;
 		int i;
@@ -620,6 +619,8 @@ static void getinfo_super1(struct supertype *st, struct mdinfo *info)
 		info->delta_disks = __le32_to_cpu(sb->delta_disks);
 		info->new_layout = __le32_to_cpu(sb->new_layout);
 		info->new_chunk = __le32_to_cpu(sb->new_chunk)<<9;
+		if (info->delta_disks < 0)
+			info->array.raid_disks -= info->delta_disks;
 	} else
 		info->reshape_active = 0;
 




More information about the pkg-mdadm-commits mailing list