md: Move check for bitmap presence to personality code.
If the superblock of a component device indicates the presence of a bitmap but the corresponding raid personality does not support bitmaps (raid0, linear, multipath, faulty), then something is seriously wrong and we'd better refuse to run such an array. Currently, this check is performed while the superblocks are examined, i.e. before entering personality code. Therefore the generic md layer must know which raid levels support bitmaps and which do not. This patch avoids this layer violation without adding identical code to various personalities. This is accomplished by introducing a new public function to md.c, md_check_no_bitmap(), which replaces the hard-coded checks in the superblock loading functions. A call to md_check_no_bitmap() is added to the ->run method of each personality which does not support bitmaps and assembly is aborted if at least one component device contains a bitmap. Signed-off-by: Andre Noll <maan@systemlinux.org> Signed-off-by: NeilBrown <neilb@suse.de>
This commit is contained in:
@@ -735,6 +735,24 @@ struct super_type {
|
||||
sector_t num_sectors);
|
||||
};
|
||||
|
||||
/*
|
||||
* Check that the given mddev has no bitmap.
|
||||
*
|
||||
* This function is called from the run method of all personalities that do not
|
||||
* support bitmaps. It prints an error message and returns non-zero if mddev
|
||||
* has a bitmap. Otherwise, it returns 0.
|
||||
*
|
||||
*/
|
||||
int md_check_no_bitmap(mddev_t *mddev)
|
||||
{
|
||||
if (!mddev->bitmap_file && !mddev->bitmap_offset)
|
||||
return 0;
|
||||
printk(KERN_ERR "%s: bitmaps are not supported for %s\n",
|
||||
mdname(mddev), mddev->pers->name);
|
||||
return 1;
|
||||
}
|
||||
EXPORT_SYMBOL(md_check_no_bitmap);
|
||||
|
||||
/*
|
||||
* load_super for 0.90.0
|
||||
*/
|
||||
@@ -788,17 +806,6 @@ static int super_90_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version
|
||||
rdev->data_offset = 0;
|
||||
rdev->sb_size = MD_SB_BYTES;
|
||||
|
||||
if (sb->state & (1<<MD_SB_BITMAP_PRESENT)) {
|
||||
if (sb->level != 1 && sb->level != 4
|
||||
&& sb->level != 5 && sb->level != 6
|
||||
&& sb->level != 10) {
|
||||
/* FIXME use a better test */
|
||||
printk(KERN_WARNING
|
||||
"md: bitmaps not supported for this level.\n");
|
||||
goto abort;
|
||||
}
|
||||
}
|
||||
|
||||
if (sb->level == LEVEL_MULTIPATH)
|
||||
rdev->desc_nr = -1;
|
||||
else
|
||||
@@ -1176,17 +1183,6 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version)
|
||||
bdevname(rdev->bdev,b));
|
||||
return -EINVAL;
|
||||
}
|
||||
if ((le32_to_cpu(sb->feature_map) & MD_FEATURE_BITMAP_OFFSET)) {
|
||||
if (sb->level != cpu_to_le32(1) &&
|
||||
sb->level != cpu_to_le32(4) &&
|
||||
sb->level != cpu_to_le32(5) &&
|
||||
sb->level != cpu_to_le32(6) &&
|
||||
sb->level != cpu_to_le32(10)) {
|
||||
printk(KERN_WARNING
|
||||
"md: bitmaps not supported for this level.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
rdev->preferred_minor = 0xffff;
|
||||
rdev->data_offset = le64_to_cpu(sb->data_offset);
|
||||
|
Reference in New Issue
Block a user