Skip to content

Commit c4d097d

Browse files
mauelshasnitm
authored andcommitted
dm raid: fix oops on upgrading to extended superblock format
When a RAID set was created on dm-raid version < 1.9.0 (old RAID superblock format), all of the new 1.9.0 members of the superblock are uninitialized (zero) -- including the device sectors member needed to support shrinking. All the other accesses to superblock fields new in 1.9.0 were reviewed and verified to be properly guarded against invalid use. The 'sectors' member was the only one used when the superblock version is < 1.9. Don't access the superblock's >= 1.9.0 'sectors' member unconditionally. Also add respective comments. Signed-off-by: Heinz Mauelshagen <heinzm@redhat.com> Signed-off-by: Mike Snitzer <snitzer@redhat.com>
1 parent feb7695 commit c4d097d

File tree

1 file changed

+14
-3
lines changed

1 file changed

+14
-3
lines changed

drivers/md/dm-raid.c

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1927,7 +1927,7 @@ struct dm_raid_superblock {
19271927
/********************************************************************
19281928
* BELOW FOLLOW V1.9.0 EXTENSIONS TO THE PRISTINE SUPERBLOCK FORMAT!!!
19291929
*
1930-
* FEATURE_FLAG_SUPPORTS_V190 in the features member indicates that those exist
1930+
* FEATURE_FLAG_SUPPORTS_V190 in the compat_features member indicates that those exist
19311931
*/
19321932

19331933
__le32 flags; /* Flags defining array states for reshaping */
@@ -2092,6 +2092,11 @@ static void super_sync(struct mddev *mddev, struct md_rdev *rdev)
20922092
sb->layout = cpu_to_le32(mddev->layout);
20932093
sb->stripe_sectors = cpu_to_le32(mddev->chunk_sectors);
20942094

2095+
/********************************************************************
2096+
* BELOW FOLLOW V1.9.0 EXTENSIONS TO THE PRISTINE SUPERBLOCK FORMAT!!!
2097+
*
2098+
* FEATURE_FLAG_SUPPORTS_V190 in the compat_features member indicates that those exist
2099+
*/
20952100
sb->new_level = cpu_to_le32(mddev->new_level);
20962101
sb->new_layout = cpu_to_le32(mddev->new_layout);
20972102
sb->new_stripe_sectors = cpu_to_le32(mddev->new_chunk_sectors);
@@ -2438,8 +2443,14 @@ static int super_validate(struct raid_set *rs, struct md_rdev *rdev)
24382443
mddev->bitmap_info.default_offset = mddev->bitmap_info.offset;
24392444

24402445
if (!test_and_clear_bit(FirstUse, &rdev->flags)) {
2441-
/* Retrieve device size stored in superblock to be prepared for shrink */
2442-
rdev->sectors = le64_to_cpu(sb->sectors);
2446+
/*
2447+
* Retrieve rdev size stored in superblock to be prepared for shrink.
2448+
* Check extended superblock members are present otherwise the size
2449+
* will not be set!
2450+
*/
2451+
if (le32_to_cpu(sb->compat_features) & FEATURE_FLAG_SUPPORTS_V190)
2452+
rdev->sectors = le64_to_cpu(sb->sectors);
2453+
24432454
rdev->recovery_offset = le64_to_cpu(sb->disk_recovery_offset);
24442455
if (rdev->recovery_offset == MaxSector)
24452456
set_bit(In_sync, &rdev->flags);

0 commit comments

Comments
 (0)