]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
md: Move check for bitmap presence to personality code.
authorAndre Noll <maan@systemlinux.org>
Wed, 17 Jun 2009 22:49:23 +0000 (08:49 +1000)
committerNeilBrown <neilb@suse.de>
Wed, 17 Jun 2009 22:49:23 +0000 (08:49 +1000)
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>
drivers/md/faulty.c
drivers/md/linear.c
drivers/md/md.c
drivers/md/md.h
drivers/md/multipath.c
drivers/md/raid0.c

index 6e83b38d931d6be62ad51e2855cf6008373abf80..87d88dbb667f2abdb83190b5d1fc1ac3d19cb1ba 100644 (file)
@@ -299,8 +299,12 @@ static int run(mddev_t *mddev)
 {
        mdk_rdev_t *rdev;
        int i;
+       conf_t *conf;
 
-       conf_t *conf = kmalloc(sizeof(*conf), GFP_KERNEL);
+       if (md_check_no_bitmap(mddev))
+               return -EINVAL;
+
+       conf = kmalloc(sizeof(*conf), GFP_KERNEL);
        if (!conf)
                return -ENOMEM;
 
index dda2f1b64a6dce3885f16cda83b525f1ed32f9cf..564c390f8a1b8127a7cda1efb35b9b25c846b397 100644 (file)
@@ -189,6 +189,8 @@ static int linear_run (mddev_t *mddev)
 {
        linear_conf_t *conf;
 
+       if (md_check_no_bitmap(mddev))
+               return -EINVAL;
        mddev->queue->queue_lock = &mddev->queue->__queue_lock;
        conf = linear_conf(mddev, mddev->raid_disks);
 
index 0f11fd1417abba31227184a52bd9d50853637231..09be637d52cbb6041a67166807f948f9a00f08f2 100644 (file)
@@ -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);
index ea2c441449d4ea617548055e3d994120ace9da80..9430a110db934013cd68e30f0cbb563d7da8323b 100644 (file)
@@ -430,5 +430,6 @@ extern void md_new_event(mddev_t *mddev);
 extern int md_allow_write(mddev_t *mddev);
 extern void md_wait_for_blocked_rdev(mdk_rdev_t *rdev, mddev_t *mddev);
 extern void md_set_array_sectors(mddev_t *mddev, sector_t array_sectors);
+extern int md_check_no_bitmap(mddev_t *mddev);
 
 #endif /* _MD_MD_H */
index c1ca63f278a94b634166996bf07c2ae7ecb771e1..cbe368fa6598758da4d55b468acd8efd0d6c8710 100644 (file)
@@ -421,6 +421,9 @@ static int multipath_run (mddev_t *mddev)
        struct multipath_info *disk;
        mdk_rdev_t *rdev;
 
+       if (md_check_no_bitmap(mddev))
+               return -EINVAL;
+
        if (mddev->level != LEVEL_MULTIPATH) {
                printk("multipath: %s: raid level not set to multipath IO (%d)\n",
                       mdname(mddev), mddev->level);
index 717e64a4af9a2f225f216c28b7e27d00979f81a3..ab4a489d8695f759e1ca4edc252f9636c5c31977 100644 (file)
@@ -314,6 +314,8 @@ static int raid0_run(mddev_t *mddev)
                printk(KERN_ERR "md/raid0: chunk size must be set.\n");
                return -EINVAL;
        }
+       if (md_check_no_bitmap(mddev))
+               return -EINVAL;
        blk_queue_max_sectors(mddev->queue, mddev->chunk_sectors);
        mddev->queue->queue_lock = &mddev->queue->__queue_lock;