[mdadm/f15: 1/2] Fix mdadm-3.2.4 introduced bug where --add fails in common cases

Jes Sorensen jsorensen at fedoraproject.org
Tue May 15 12:32:14 UTC 2012


commit aa53f3daa84c3a0c422a159295ef1b0db6efdff0
Author: Jes Sorensen <Jes.Sorensen at redhat.com>
Date:   Tue May 15 14:30:56 2012 +0200

    Fix mdadm-3.2.4 introduced bug where --add fails in common cases
    
    Resolves: bz821717 (f17) bz821718 (f16) bz821719 (f15)
    
    Signed-off-by: Jes Sorensen <Jes.Sorensen at redhat.com>

 mdadm-3.2.4-super1-fix-choice-of-data_offset.patch |   92 ++++++++++++++++++++
 mdadm.spec                                         |    8 ++-
 2 files changed, 99 insertions(+), 1 deletions(-)
---
diff --git a/mdadm-3.2.4-super1-fix-choice-of-data_offset.patch b/mdadm-3.2.4-super1-fix-choice-of-data_offset.patch
new file mode 100644
index 0000000..62a5ef1
--- /dev/null
+++ b/mdadm-3.2.4-super1-fix-choice-of-data_offset.patch
@@ -0,0 +1,92 @@
+From d9751e06a601b5576b1b9e2c8126584083110ca5 Mon Sep 17 00:00:00 2001
+From: NeilBrown <neilb at suse.de>
+Date: Tue, 15 May 2012 09:51:03 +1000
+Subject: [PATCH] super1: fix choice of data_offset.
+
+While it is nice to set a high data_offset to leave plenty of head
+room it is much more important to leave enough space to allow
+of the data of the array.
+So after we check that sb->size is still available, only reduce the
+'reserved', don't increase it.
+
+This fixes a bug where --adding a spare fails because it does not have
+enough space in it.
+
+Reported-by: nowhere <nowhere at hakkenden.ath.cx>
+Signed-off-by: NeilBrown <neilb at suse.de>
+---
+ super1.c |   31 ++++++++++++++++---------------
+ 1 files changed, 16 insertions(+), 15 deletions(-)
+
+diff --git a/super1.c b/super1.c
+index be77c33..4f20cc3 100644
+--- a/super1.c
++++ b/super1.c
+@@ -1189,40 +1189,42 @@ static int write_init_super1(struct supertype *st)
+ 		case 1:
+ 			sb->super_offset = __cpu_to_le64(0);
+ 			reserved = bm_space + 4*2;
++			if (reserved < headroom)
++				reserved = headroom;
++			if (reserved + array_size > dsize)
++				reserved = dsize - array_size;
+ 			/* Try for multiple of 1Meg so it is nicely aligned */
+ 			#define ONE_MEG (2*1024)
+-			reserved = ((reserved + ONE_MEG-1)/ONE_MEG) * ONE_MEG;
+-			if (reserved + __le64_to_cpu(sb->size) > dsize)
+-				reserved = dsize - __le64_to_cpu(sb->size);
++			if (reserved > ONE_MEG)
++				reserved = (reserved/ONE_MEG) * ONE_MEG;
++
+ 			/* force 4K alignment */
+ 			reserved &= ~7ULL;
+ 
+-			if (reserved < headroom)
+-				reserved = headroom;
+-
+ 			sb->data_offset = __cpu_to_le64(reserved);
+ 			sb->data_size = __cpu_to_le64(dsize - reserved);
+ 			break;
+ 		case 2:
+ 			sb_offset = 4*2;
+ 			sb->super_offset = __cpu_to_le64(4*2);
+-			if (4*2 + 4*2 + bm_space + __le64_to_cpu(sb->size)
++			if (4*2 + 4*2 + bm_space + array_size
+ 			    > dsize)
+-				bm_space = dsize - __le64_to_cpu(sb->size)
++				bm_space = dsize - array_size
+ 					- 4*2 - 4*2;
+ 
+ 			reserved = bm_space + 4*2 + 4*2;
++			if (reserved < headroom)
++				reserved = headroom;
++			if (reserved + array_size > dsize)
++				reserved = dsize - array_size;
+ 			/* Try for multiple of 1Meg so it is nicely aligned */
+ 			#define ONE_MEG (2*1024)
+-			reserved = ((reserved + ONE_MEG-1)/ONE_MEG) * ONE_MEG;
+-			if (reserved + __le64_to_cpu(sb->size) > dsize)
+-				reserved = dsize - __le64_to_cpu(sb->size);
++			if (reserved > ONE_MEG)
++				reserved = (reserved/ONE_MEG) * ONE_MEG;
++
+ 			/* force 4K alignment */
+ 			reserved &= ~7ULL;
+ 
+-			if (reserved < headroom)
+-				reserved = headroom;
+-
+ 			sb->data_offset = __cpu_to_le64(reserved);
+ 			sb->data_size = __cpu_to_le64(dsize - reserved);
+ 			break;
+@@ -1234,7 +1236,6 @@ static int write_init_super1(struct supertype *st)
+ 			goto out;
+ 		}
+ 
+-
+ 		sb->sb_csum = calc_sb_1_csum(sb);
+ 		rv = store_super1(st, di->fd);
+ 		if (rv == 0 && (__le32_to_cpu(sb->feature_map) & 1))
+-- 
+1.7.7.6
+
diff --git a/mdadm.spec b/mdadm.spec
index 9eb6b97..7bf6615 100644
--- a/mdadm.spec
+++ b/mdadm.spec
@@ -1,7 +1,7 @@
 Summary:     The mdadm program controls Linux md devices (software RAID arrays)
 Name:        mdadm
 Version:     3.2.4
-Release:     2%{?dist}
+Release:     3%{?dist}
 Source:      http://www.kernel.org/pub/linux/utils/raid/mdadm/mdadm-%{version}.tar.xz
 Source1:     mdmonitor.init
 Source2:     raid-check
@@ -11,6 +11,7 @@ Source5:     mdadm-cron
 Source6:     mdmonitor.service
 Source7:     mdmonitor-takeover.service
 Source8:     mdadm.conf
+Patch1:	     mdadm-3.2.4-super1-fix-choice-of-data_offset.patch
 # Fedora customization patches
 Patch97:     mdadm-3.2.3-udev.patch
 Patch98:     mdadm-2.5.2-static.patch
@@ -49,6 +50,7 @@ is not used as the system init process.
 %prep
 %setup -q
 
+%patch1 -p1 -b .add
 # Fedora customization patches
 %patch97 -p1 -b .udev
 %patch98 -p1 -b .static
@@ -128,6 +130,10 @@ fi
 %{_initrddir}/*
 
 %changelog
+* Tue May 15 2012 Jes Sorensen <Jes.Sorensen at redhat.com> - 3.2.4-3
+- Fix mdadm-3.2.4 introduced bug where --add fails in common cases
+- Resolves bz821717 (f17) bz821718 (f16) bz821719 (f15)
+
 * Thu May 10 2012 Jes Sorensen <Jes.Sorensen at redhat.com> - 3.2.4-2
 - Fix mdadm.conf to use 'd' for /var/run/mdadm creation, to avoid the
   map file getting deleted during boot.


More information about the scm-commits mailing list