|
@@ -789,8 +789,7 @@ struct dm_raid_superblock {
|
|
|
__le32 layout;
|
|
|
__le32 stripe_sectors;
|
|
|
|
|
|
- __u8 pad[452]; /* Round struct to 512 bytes. */
|
|
|
- /* Always set to 0 when writing. */
|
|
|
+ /* Remainder of a logical block is zero-filled when writing (see super_sync()). */
|
|
|
} __packed;
|
|
|
|
|
|
static int read_disk_sb(struct md_rdev *rdev, int size)
|
|
@@ -827,7 +826,7 @@ static void super_sync(struct mddev *mddev, struct md_rdev *rdev)
|
|
|
test_bit(Faulty, &(rs->dev[i].rdev.flags)))
|
|
|
failed_devices |= (1ULL << i);
|
|
|
|
|
|
- memset(sb, 0, sizeof(*sb));
|
|
|
+ memset(sb + 1, 0, rdev->sb_size - sizeof(*sb));
|
|
|
|
|
|
sb->magic = cpu_to_le32(DM_RAID_MAGIC);
|
|
|
sb->features = cpu_to_le32(0); /* No features yet */
|
|
@@ -862,7 +861,11 @@ static int super_load(struct md_rdev *rdev, struct md_rdev *refdev)
|
|
|
uint64_t events_sb, events_refsb;
|
|
|
|
|
|
rdev->sb_start = 0;
|
|
|
- rdev->sb_size = sizeof(*sb);
|
|
|
+ rdev->sb_size = bdev_logical_block_size(rdev->meta_bdev);
|
|
|
+ if (rdev->sb_size < sizeof(*sb) || rdev->sb_size > PAGE_SIZE) {
|
|
|
+ DMERR("superblock size of a logical block is no longer valid");
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
|
|
|
ret = read_disk_sb(rdev, rdev->sb_size);
|
|
|
if (ret)
|