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

STALE6309d

4 messages, 2 authors, 2009-05-29 · open the first message on its own page

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

From: Andre Noll <hidden>
Date: 2009-05-29 13:18:40

Here are the first two patches for pushing down raid level dependent
code from md.c to the corresponding personalities.

The first patch is trivial as it moves only a printk() to the
personalities. The second patch removes knowledge about bitmaps
from md.c.

If the general approach used by the second patch is agreed with, I
will follow up with patches that deal with data integrity registration
and multipath handling which are the remaining two issues where md.c
does what should be handled in personality code.

Thanks
Andre
-- 
1.5.4.3

[PATCH 1/2] md: Push down reconstruction log message to personality code.

From: Andre Noll <hidden>
Date: 2009-05-29 13:18:41

Currently, the md layer checks in analyze_sbs() if the raid level
supports reconstruction (mddev->level >= 1) and if reconstruction is
in progress (mddev->recovery_cp != MaxSector).

Move that printk into the personality code of those raid levels that
care (levels 1, 4, 5, 6, 10).

Signed-off-by: Andre Noll <redacted>
---
 drivers/md/md.c     |    9 ---------
 drivers/md/raid1.c  |    4 ++++
 drivers/md/raid10.c |    4 ++++
 drivers/md/raid5.c  |    4 ++++
 4 files changed, 12 insertions(+), 9 deletions(-)
diff --git a/drivers/md/md.c b/drivers/md/md.c
index a54ec91..1d71cc2 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -2597,15 +2597,6 @@ static void analyze_sbs(mddev_t * mddev)
 			clear_bit(In_sync, &rdev->flags);
 		}
 	}
-
-
-
-	if (mddev->recovery_cp != MaxSector &&
-	    mddev->level >= 1)
-		printk(KERN_ERR "md: %s: raid array is not clean"
-		       " -- starting background reconstruction\n",
-		       mdname(mddev));
-
 }
 
 static void md_safemode_timeout(unsigned long data);
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 4692a8a..d29842f 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -2052,6 +2052,10 @@ static int run(mddev_t *mddev)
 		goto out_free_conf;
 	}
 
+	if (mddev->recovery_cp != MaxSector)
+		printk(KERN_NOTICE "raid1: %s is not clean"
+		       " -- starting background reconstruction\n",
+		       mdname(mddev));
 	printk(KERN_INFO 
 		"raid1: raid set %s active with %d out of %d mirrors\n",
 		mdname(mddev), mddev->raid_disks - mddev->degraded, 
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index d75cb96..c317543 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -2186,6 +2186,10 @@ static int run(mddev_t *mddev)
 		goto out_free_conf;
 	}
 
+	if (mddev->recovery_cp != MaxSector)
+		printk(KERN_NOTICE "raid10: %s is not clean"
+		       " -- starting background reconstruction\n",
+		       mdname(mddev));
 	printk(KERN_INFO
 		"raid10: raid set %s active with %d out of %d devices\n",
 		mdname(mddev), mddev->raid_disks - mddev->degraded,
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 9ec505b..cdd5b49 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -4454,6 +4454,10 @@ static int run(mddev_t *mddev)
 	int working_disks = 0;
 	mdk_rdev_t *rdev;
 
+	if (mddev->recovery_cp != MaxSector)
+		printk(KERN_NOTICE "raid5: %s is not clean"
+		       " -- starting background reconstruction\n",
+		       mdname(mddev));
 	if (mddev->reshape_position != MaxSector) {
 		/* Check that we can continue the reshape.
 		 * Currently only disks can change, it must
-- 
1.5.4.3

[PATCH 2/2] md: Move check for bitmap presence to personality code.

From: Andre Noll <hidden>
Date: 2009-05-29 13:18:42

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_bitmap_present(), which replaces the
hard-coded checks in the superblock loading functions.

A call to md_bitmap_present() 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 <redacted>
---
 drivers/md/faulty.c    |    6 +++-
 drivers/md/linear.c    |    2 +
 drivers/md/md.c        |   64 +++++++++++++++++++++++++++++++----------------
 drivers/md/md.h        |    1 +
 drivers/md/multipath.c |    3 ++
 drivers/md/raid0.c     |    2 +
 6 files changed, 55 insertions(+), 23 deletions(-)
diff --git a/drivers/md/faulty.c b/drivers/md/faulty.c
index 8695809..cec5d1e 100644
--- a/drivers/md/faulty.c
+++ b/drivers/md/faulty.c
@@ -298,8 +298,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_bitmap_present(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 ead1051..2ca5514 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_bitmap_present(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 1d71cc2..32e3197 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -748,6 +748,48 @@ struct super_type  {
 };
 
 /*
+ * Determine if at least one rdev contains a bitmap.
+ *
+ * Iterate over the component devices in mddev, print an error message and
+ * return non-zero on the first rdev whose superblock indicates the presence of
+ * a bitmap. Return 0 if no component device of mddev contains a bitmap.
+ *
+ * This is supposed to be called in the run method of all personalities that do
+ * not support bitmaps.
+ */
+int md_bitmap_present(mddev_t *mddev)
+{
+	mdk_rdev_t *rdev;
+	char b[BDEVNAME_SIZE];
+
+	list_for_each_entry(rdev, &mddev->disks, same_set) {
+		if (!rdev->sb_loaded || !rdev->sb_page)
+			continue;
+		switch (mddev->major_version) {
+		case 0: {
+			mdp_super_t *sb = page_address(rdev->sb_page);
+			if (sb->state & (1 << MD_SB_BITMAP_PRESENT))
+				goto whine;
+			}
+		case 1: {
+			struct mdp_superblock_1 *sb =
+				page_address(rdev->sb_page);
+			if ((le32_to_cpu(sb->feature_map) &
+					MD_FEATURE_BITMAP_OFFSET))
+				goto whine;
+			}
+		}
+	}
+	return 0;
+whine:
+	printk(KERN_ERR "%s: %s contains a bitmap but"
+		"bitmaps are not supported for %s\n", mdname(mddev),
+		bdevname(rdev->bdev, b), 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 +842,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 +1219,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 4274cdc..903479f 100644
--- a/drivers/md/md.h
+++ b/drivers/md/md.h
@@ -438,5 +438,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_bitmap_present(mddev_t *mddev);
 
 #endif /* _MD_MD_H */
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c
index ca387ba..d11285c 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_bitmap_present(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 7d680bc..9d6f14e 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_bitmap_present(mddev))
+		return -EINVAL;
 	blk_queue_max_sectors(mddev->queue, mddev->chunk_sectors);
 	mddev->queue->queue_lock = &mddev->queue->__queue_lock;
 
-- 
1.5.4.3

Re: [PATCH 1/2] md: Push down reconstruction log message to personality code.

From: Raz <hidden>
Date: 2009-05-29 20:49:40

Meil/Andre Hello
I am happy to see this patch. I have lots of "md" mess with the raid0
reshape because of some md "assumptions".
1. in md_do_sync , max_sectors is determined to be dev_sectors.
Currently I had to patch to be
   array_sectors in the case of level=0.
2.  in procedure super_90_sync the minor version is determined  by the
reshape position ?
     So now, when i reshape I see that the minor version simply changes .

thank you
raz


On Fri, May 29, 2009 at 4:18 PM, Andre Noll [off-list ref] wrote:
quoted hunk
Currently, the md layer checks in analyze_sbs() if the raid level
supports reconstruction (mddev->level >= 1) and if reconstruction is
in progress (mddev->recovery_cp != MaxSector).

Move that printk into the personality code of those raid levels that
care (levels 1, 4, 5, 6, 10).

Signed-off-by: Andre Noll <redacted>
---
 drivers/md/md.c     |    9 ---------
 drivers/md/raid1.c  |    4 ++++
 drivers/md/raid10.c |    4 ++++
 drivers/md/raid5.c  |    4 ++++
 4 files changed, 12 insertions(+), 9 deletions(-)
diff --git a/drivers/md/md.c b/drivers/md/md.c
index a54ec91..1d71cc2 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -2597,15 +2597,6 @@ static void analyze_sbs(mddev_t * mddev)
                       clear_bit(In_sync, &rdev->flags);
               }
       }
-
-
-
-       if (mddev->recovery_cp != MaxSector &&
-           mddev->level >= 1)
-               printk(KERN_ERR "md: %s: raid array is not clean"
-                      " -- starting background reconstruction\n",
-                      mdname(mddev));
-
 }

 static void md_safemode_timeout(unsigned long data);
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 4692a8a..d29842f 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -2052,6 +2052,10 @@ static int run(mddev_t *mddev)
               goto out_free_conf;
       }

+       if (mddev->recovery_cp != MaxSector)
+               printk(KERN_NOTICE "raid1: %s is not clean"
+                      " -- starting background reconstruction\n",
+                      mdname(mddev));
       printk(KERN_INFO
               "raid1: raid set %s active with %d out of %d mirrors\n",
               mdname(mddev), mddev->raid_disks - mddev->degraded,
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index d75cb96..c317543 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -2186,6 +2186,10 @@ static int run(mddev_t *mddev)
               goto out_free_conf;
       }

+       if (mddev->recovery_cp != MaxSector)
+               printk(KERN_NOTICE "raid10: %s is not clean"
+                      " -- starting background reconstruction\n",
+                      mdname(mddev));
       printk(KERN_INFO
               "raid10: raid set %s active with %d out of %d devices\n",
               mdname(mddev), mddev->raid_disks - mddev->degraded,
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 9ec505b..cdd5b49 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -4454,6 +4454,10 @@ static int run(mddev_t *mddev)
       int working_disks = 0;
       mdk_rdev_t *rdev;

+       if (mddev->recovery_cp != MaxSector)
+               printk(KERN_NOTICE "raid5: %s is not clean"
+                      " -- starting background reconstruction\n",
+                      mdname(mddev));
       if (mddev->reshape_position != MaxSector) {
               /* Check that we can continue the reshape.
                * Currently only disks can change, it must
--
1.5.4.3

--
To unsubscribe from this list: send the line "unsubscribe linux-raid" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-raid" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help