Re: [PATCH/RFC 0/2] md: personality pushdown patches -- intro

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 08:19, Neil Brown wrote:

> The second is heading in the right direction.
> However md_bitmap_present is as much of a layering violation in its
> own way as the previous code was - diving in to the metatype_type
> specific data.
> 
> You will notice in bitmap_create that an array has a bitmap if and
> only if (mddev->bitmap_file || mddev->bitmap_offset).
> So that is the test which should be used in md_bitmap_present.

I see. And this makes the code much simpler. In fact it's so simple
that we might probably want to inline it.

> Also the function name "md_bitmap_present" give no hint that it will
> report an error - it reads like a simple test.
> Maybe "md_check_no_bitmap" to indicate what the function is expecting
> to find?

Yup, md_check_no_bitmap is more descriptive. The patch below addresses
both issues.

Thanks
Andre
---

commit cb2e46af5393cfed1b46182e2ca19a4adb7a4e0d
Author: Andre Noll <maan@xxxxxxxxxxxxxxx>
Date:   Tue Jun 2 21:49:29 2009 +0200

    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@xxxxxxxxxxxxxxx>

diff --git a/drivers/md/faulty.c b/drivers/md/faulty.c
index 6e83b38..87d88db 100644
--- a/drivers/md/faulty.c
+++ b/drivers/md/faulty.c
@@ -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;
 
diff --git a/drivers/md/linear.c b/drivers/md/linear.c
index 56c46e0..f9c713d 100644
--- a/drivers/md/linear.c
+++ b/drivers/md/linear.c
@@ -183,6 +183,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);
 
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 812a1f7..aaeaa69 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -748,6 +748,24 @@ struct super_type  {
 };
 
 /*
+ * 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_bitmap_present);
+
+/*
  * load_super for 0.90.0 
  */
 static int super_90_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version)
@@ -800,17 +818,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
@@ -1188,17 +1195,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);
diff --git a/drivers/md/md.h b/drivers/md/md.h
index bac7c2b..ccc0ace 100644
--- a/drivers/md/md.h
+++ b/drivers/md/md.h
@@ -437,5 +437,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 */
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c
index ca387ba..fb8a5e7 100644
--- a/drivers/md/multipath.c
+++ b/drivers/md/multipath.c
@@ -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);
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c
index 0fcd9b5..3c78b42 100644
--- a/drivers/md/raid0.c
+++ b/drivers/md/raid0.c
@@ -311,6 +311,8 @@ static int raid0_run(mddev_t *mddev)
 		printk(KERN_ERR "md/raid0: chunk size must be a power of 2.\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;
 
-- 
The only person who always got his work done by Friday was Robinson Crusoe

Attachment: signature.asc
Description: Digital signature


[Index of Archives]     [Linux RAID Wiki]     [ATA RAID]     [Linux SCSI Target Infrastructure]     [Linux Block]     [Linux IDE]     [Linux SCSI]     [Linux Hams]     [Device Mapper]     [Device Mapper Cryptographics]     [Kernel]     [Linux Admin]     [Linux Net]     [GFS]     [RPM]     [git]     [Yosemite Forum]


  Powered by Linux