--- /dev/null
+From c4647292fda0833bebe45be27f04453b736981fa Mon Sep 17 00:00:00 2001
+From: NeilBrown <neilb@suse.de>
+Date: Thu, 7 May 2009 12:51:06 +1000
+Subject: [PATCH] md: remove rd%d links immediately after stopping an array.
+
+md maintains link in sys/mdXX/md/ to identify which device has
+which role in the array. e.g.
+ rd2 -> dev-sda
+
+indicates that the device with role '2' in the array is sda.
+
+These links are only present when the array is active. They are
+created immediately after ->run is called, and so should be removed
+immediately after ->stop is called.
+However they are currently removed a little bit later, and it is
+possible for ->run to be called again, thus adding these links, before
+they are removed.
+
+So move the removal earlier so they are consistently only present when
+the array is active.
+
+Signed-off-by: NeilBrown <neilb@suse.de>
+---
+ drivers/md/md.c | 17 ++++++++---------
+ 1 file changed, 8 insertions(+), 9 deletions(-)
+
+--- linux-2.6.27-SLE11_BRANCH.orig/drivers/md/md.c
++++ linux-2.6.27-SLE11_BRANCH/drivers/md/md.c
+@@ -3960,6 +3960,7 @@ static int do_md_stop(mddev_t * mddev, i
+ {
+ int err = 0;
+ struct gendisk *disk = mddev->gendisk;
++ mdk_rdev_t *rdev;
+
+ if (atomic_read(&mddev->openers) > is_open) {
+ printk("md: %s still in use.\n",mdname(mddev));
+@@ -4002,6 +4003,13 @@ static int do_md_stop(mddev_t * mddev, i
+ /* tell userspace to handle 'inactive' */
+ sysfs_notify(&mddev->kobj, NULL, "array_state");
+
++ list_for_each_entry(rdev, &mddev->disks, same_set)
++ if (rdev->raid_disk >= 0) {
++ char nm[20];
++ sprintf(nm, "rd%d", rdev->raid_disk);
++ sysfs_remove_link(&mddev->kobj, nm);
++ }
++
+ set_capacity(disk, 0);
+ mddev->changed = 1;
+
+@@ -4022,8 +4030,6 @@ static int do_md_stop(mddev_t * mddev, i
+ * Free resources if final stop
+ */
+ if (mode == 0) {
+- mdk_rdev_t *rdev;
+- struct list_head *tmp;
+
+ printk(KERN_INFO "md: %s stopped.\n", mdname(mddev));
+
+@@ -4035,13 +4041,6 @@ static int do_md_stop(mddev_t * mddev, i
+ }
+ mddev->bitmap_offset = 0;
+
+- rdev_for_each(rdev, tmp, mddev)
+- if (rdev->raid_disk >= 0) {
+- char nm[20];
+- sprintf(nm, "rd%d", rdev->raid_disk);
+- sysfs_remove_link(&mddev->kobj, nm);
+- }
+-
+ /* make sure all md_delayed_delete calls have finished */
+ flush_scheduled_work();
+