]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
md: Handle growth of v1.x metadata correctly.
authorNeil Brown <neilb@suse.de>
Thu, 6 Aug 2009 05:53:57 +0000 (15:53 +1000)
committerGreg Kroah-Hartman <gregkh@suse.de>
Sun, 16 Aug 2009 21:18:57 +0000 (14:18 -0700)
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

index 6021dea894da5b2e87506986e8c11a6ec57105a5..751a315caa51d9c9b1202101ea02b25c622b91ff 100644 (file)
@@ -1410,8 +1410,14 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev)
                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);