aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndre Noll <maan@systemlinux.org>2009-06-17 18:49:23 -0400
committerNeilBrown <neilb@suse.de>2009-06-17 18:49:23 -0400
commit0894cc3066aaa3e75a99383c0d25feebf9b688ac (patch)
tree651664e6b288e36dc9553443e334e650139851c8
parent8190e754e0723de7cecb80bdd9eb93911dfa04a1 (diff)
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>
-rw-r--r--drivers/md/faulty.c6
-rw-r--r--drivers/md/linear.c2
-rw-r--r--drivers/md/md.c40
-rw-r--r--drivers/md/md.h1
-rw-r--r--drivers/md/multipath.c3
-rw-r--r--drivers/md/raid0.c2
6 files changed, 31 insertions, 23 deletions
diff --git a/drivers/md/faulty.c b/drivers/md/faulty.c
index 6e83b38d931d..87d88dbb667f 100644
--- a/drivers/md/faulty.c
+++ b/drivers/md/faulty.c
@@ -299,8 +299,12 @@ static int run(mddev_t *mddev)
299{ 299{
300 mdk_rdev_t *rdev; 300 mdk_rdev_t *rdev;
301 int i; 301 int i;
302 conf_t *conf;
302 303
303 conf_t *conf = kmalloc(sizeof(*conf), GFP_KERNEL); 304 if (md_check_no_bitmap(mddev))
305 return -EINVAL;
306
307 conf = kmalloc(sizeof(*conf), GFP_KERNEL);
304 if (!conf) 308 if (!conf)
305 return -ENOMEM; 309 return -ENOMEM;
306 310
diff --git a/drivers/md/linear.c b/drivers/md/linear.c
index dda2f1b64a6d..564c390f8a1b 100644
--- a/drivers/md/linear.c
+++ b/drivers/md/linear.c
@@ -189,6 +189,8 @@ static int linear_run (mddev_t *mddev)
189{ 189{
190 linear_conf_t *conf; 190 linear_conf_t *conf;
191 191
192 if (md_check_no_bitmap(mddev))
193 return -EINVAL;
192 mddev->queue->queue_lock = &mddev->queue->__queue_lock; 194 mddev->queue->queue_lock = &mddev->queue->__queue_lock;
193 conf = linear_conf(mddev, mddev->raid_disks); 195 conf = linear_conf(mddev, mddev->raid_disks);
194 196
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 0f11fd1417ab..09be637d52cb 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -736,6 +736,24 @@ struct super_type {
736}; 736};
737 737
738/* 738/*
739 * Check that the given mddev has no bitmap.
740 *
741 * This function is called from the run method of all personalities that do not
742 * support bitmaps. It prints an error message and returns non-zero if mddev
743 * has a bitmap. Otherwise, it returns 0.
744 *
745 */
746int md_check_no_bitmap(mddev_t *mddev)
747{
748 if (!mddev->bitmap_file && !mddev->bitmap_offset)
749 return 0;
750 printk(KERN_ERR "%s: bitmaps are not supported for %s\n",
751 mdname(mddev), mddev->pers->name);
752 return 1;
753}
754EXPORT_SYMBOL(md_check_no_bitmap);
755
756/*
739 * load_super for 0.90.0 757 * load_super for 0.90.0
740 */ 758 */
741static int super_90_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version) 759static int super_90_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version)
@@ -788,17 +806,6 @@ static int super_90_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version
788 rdev->data_offset = 0; 806 rdev->data_offset = 0;
789 rdev->sb_size = MD_SB_BYTES; 807 rdev->sb_size = MD_SB_BYTES;
790 808
791 if (sb->state & (1<<MD_SB_BITMAP_PRESENT)) {
792 if (sb->level != 1 && sb->level != 4
793 && sb->level != 5 && sb->level != 6
794 && sb->level != 10) {
795 /* FIXME use a better test */
796 printk(KERN_WARNING
797 "md: bitmaps not supported for this level.\n");
798 goto abort;
799 }
800 }
801
802 if (sb->level == LEVEL_MULTIPATH) 809 if (sb->level == LEVEL_MULTIPATH)
803 rdev->desc_nr = -1; 810 rdev->desc_nr = -1;
804 else 811 else
@@ -1176,17 +1183,6 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version)
1176 bdevname(rdev->bdev,b)); 1183 bdevname(rdev->bdev,b));
1177 return -EINVAL; 1184 return -EINVAL;
1178 } 1185 }
1179 if ((le32_to_cpu(sb->feature_map) & MD_FEATURE_BITMAP_OFFSET)) {
1180 if (sb->level != cpu_to_le32(1) &&
1181 sb->level != cpu_to_le32(4) &&
1182 sb->level != cpu_to_le32(5) &&
1183 sb->level != cpu_to_le32(6) &&
1184 sb->level != cpu_to_le32(10)) {
1185 printk(KERN_WARNING
1186 "md: bitmaps not supported for this level.\n");
1187 return -EINVAL;
1188 }
1189 }
1190 1186
1191 rdev->preferred_minor = 0xffff; 1187 rdev->preferred_minor = 0xffff;
1192 rdev->data_offset = le64_to_cpu(sb->data_offset); 1188 rdev->data_offset = le64_to_cpu(sb->data_offset);
diff --git a/drivers/md/md.h b/drivers/md/md.h
index ea2c441449d4..9430a110db93 100644
--- a/drivers/md/md.h
+++ b/drivers/md/md.h
@@ -430,5 +430,6 @@ extern void md_new_event(mddev_t *mddev);
430extern int md_allow_write(mddev_t *mddev); 430extern int md_allow_write(mddev_t *mddev);
431extern void md_wait_for_blocked_rdev(mdk_rdev_t *rdev, mddev_t *mddev); 431extern void md_wait_for_blocked_rdev(mdk_rdev_t *rdev, mddev_t *mddev);
432extern void md_set_array_sectors(mddev_t *mddev, sector_t array_sectors); 432extern void md_set_array_sectors(mddev_t *mddev, sector_t array_sectors);
433extern int md_check_no_bitmap(mddev_t *mddev);
433 434
434#endif /* _MD_MD_H */ 435#endif /* _MD_MD_H */
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c
index c1ca63f278a9..cbe368fa6598 100644
--- a/drivers/md/multipath.c
+++ b/drivers/md/multipath.c
@@ -421,6 +421,9 @@ static int multipath_run (mddev_t *mddev)
421 struct multipath_info *disk; 421 struct multipath_info *disk;
422 mdk_rdev_t *rdev; 422 mdk_rdev_t *rdev;
423 423
424 if (md_check_no_bitmap(mddev))
425 return -EINVAL;
426
424 if (mddev->level != LEVEL_MULTIPATH) { 427 if (mddev->level != LEVEL_MULTIPATH) {
425 printk("multipath: %s: raid level not set to multipath IO (%d)\n", 428 printk("multipath: %s: raid level not set to multipath IO (%d)\n",
426 mdname(mddev), mddev->level); 429 mdname(mddev), mddev->level);
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c
index 717e64a4af9a..ab4a489d8695 100644
--- a/drivers/md/raid0.c
+++ b/drivers/md/raid0.c
@@ -314,6 +314,8 @@ static int raid0_run(mddev_t *mddev)
314 printk(KERN_ERR "md/raid0: chunk size must be set.\n"); 314 printk(KERN_ERR "md/raid0: chunk size must be set.\n");
315 return -EINVAL; 315 return -EINVAL;
316 } 316 }
317 if (md_check_no_bitmap(mddev))
318 return -EINVAL;
317 blk_queue_max_sectors(mddev->queue, mddev->chunk_sectors); 319 blk_queue_max_sectors(mddev->queue, mddev->chunk_sectors);
318 mddev->queue->queue_lock = &mddev->queue->__queue_lock; 320 mddev->queue->queue_lock = &mddev->queue->__queue_lock;
319 321