--- /dev/null
+From neilb@suse.de Thu Aug 6 13:23:07 2009
+From: Neil Brown <neilb@suse.de>
+Date: Thu, 6 Aug 2009 15:53:57 +1000
+Subject: md: Handle growth of v1.x metadata correctly.
+To: Greg KH <greg@kroah.com>
+Cc: stable@kernel.org
+Message-ID: <19066.28661.194843.385976@notabene.brown>
+
+
+From: Neil Brown <neilb@suse.de>
+
+commit 70471dafe3390243c598a3165dfb86b8b8b3f4fe upstream.
+
+The v1.x metadata does not have a fixed size and can grow
+when devices are added.
+If it grows enough to require an extra sector of storage,
+we need to update the 'sb_size' to match.
+
+Without this, md can write out an incomplete superblock with a
+bad checksum, which will be rejected when trying to re-assemble
+the array.
+
+Signed-off-by: NeilBrown <neilb@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/md/md.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+--- a/drivers/md/md.c
++++ b/drivers/md/md.c
+@@ -1410,8 +1410,14 @@ static void super_1_sync(mddev_t *mddev,
+ if (rdev2->desc_nr+1 > max_dev)
+ max_dev = rdev2->desc_nr+1;
+
+- if (max_dev > le32_to_cpu(sb->max_dev))
++ if (max_dev > le32_to_cpu(sb->max_dev)) {
++ int bmask;
+ sb->max_dev = cpu_to_le32(max_dev);
++ rdev->sb_size = max_dev * 2 + 256;
++ bmask = queue_hardsect_size(rdev->bdev->bd_disk->queue)-1;
++ if (rdev->sb_size & bmask)
++ rdev->sb_size = (rdev->sb_size | bmask) + 1;
++ }
+ for (i=0; i<max_dev;i++)
+ sb->dev_roles[i] = cpu_to_le16(0xfffe);
+