Neil, I read through the md code this afternoon looking for uses of mddev->disks, and protected each use with reconfig_sem. These three are the only three I saw. Ross Vandegrift ross@willow.seitz.com
--- md.c.orig Wed Feb 27 16:04:50 2002 +++ md.c Wed Feb 27 20:42:41 2002 @@ -606,7 +606,9 @@ mdidx(mddev), partition_name(rdev->dev), partition_name(same_pdev->dev)); + down(&mddev->reconfig_sem); md_list_add(&rdev->same_set, &mddev->disks); + up(&mddev->reconfig_sem); rdev->mddev = mddev; mddev->nb_dev++; printk(KERN_INFO "md: bind<%s,%d>\n", partition_name(rdev->dev), mddev->nb_dev); @@ -1889,10 +1891,13 @@ struct md_list_head *tmp; int err; + down(&mddev->reconfig_sem); if (mddev->disks.prev == &mddev->disks) { + up(&mddev->reconfig_sem); MD_BUG(); return; } + up(&mddev->reconfig_sem); printk(KERN_INFO "md: running: "); @@ -2204,8 +2209,11 @@ return -EINVAL; } if (mddev->nb_dev) { - mdk_rdev_t *rdev0 = md_list_entry(mddev->disks.next, + mdk_rdev_t *rdev0; + down(&mddev->reconfig_sem); + rdev0 = md_list_entry(mddev->disks.next, mdk_rdev_t, same_set); + up(&mddev->reconfig_sem); if (!uuid_equal(rdev0, rdev)) { printk(KERN_WARNING "md: %s has different UUID to %s\n", partition_name(rdev->dev), partition_name(rdev0->dev));