aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-03-09 23:50:11 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-03-09 23:50:11 -0400
commitbad948ffee7cbf73a7dd3e4b8272985d5c3c8b55 (patch)
tree0bc675ff15d51bac630f03acaeb157aef0ede280
parent99adcd9d67aaf04e28f5ae96df280f236bde4b66 (diff)
parent5fd3a17ed456637a224cf4ca82b9ad9d005bc8d4 (diff)
Merge branch 'for-linus' of git://neil.brown.name/md
* 'for-linus' of git://neil.brown.name/md: md: fix deadlock when stopping arrays
-rw-r--r--drivers/md/md.c30
1 files changed, 18 insertions, 12 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 03b4cd0a6344..a307f87eb90e 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -214,12 +214,7 @@ static inline mddev_t *mddev_get(mddev_t *mddev)
214 return mddev; 214 return mddev;
215} 215}
216 216
217static void mddev_delayed_delete(struct work_struct *ws) 217static void mddev_delayed_delete(struct work_struct *ws);
218{
219 mddev_t *mddev = container_of(ws, mddev_t, del_work);
220 kobject_del(&mddev->kobj);
221 kobject_put(&mddev->kobj);
222}
223 218
224static void mddev_put(mddev_t *mddev) 219static void mddev_put(mddev_t *mddev)
225{ 220{
@@ -3542,6 +3537,21 @@ static struct kobj_type md_ktype = {
3542 3537
3543int mdp_major = 0; 3538int mdp_major = 0;
3544 3539
3540static void mddev_delayed_delete(struct work_struct *ws)
3541{
3542 mddev_t *mddev = container_of(ws, mddev_t, del_work);
3543
3544 if (mddev->private == &md_redundancy_group) {
3545 sysfs_remove_group(&mddev->kobj, &md_redundancy_group);
3546 if (mddev->sysfs_action)
3547 sysfs_put(mddev->sysfs_action);
3548 mddev->sysfs_action = NULL;
3549 mddev->private = NULL;
3550 }
3551 kobject_del(&mddev->kobj);
3552 kobject_put(&mddev->kobj);
3553}
3554
3545static int md_alloc(dev_t dev, char *name) 3555static int md_alloc(dev_t dev, char *name)
3546{ 3556{
3547 static DEFINE_MUTEX(disks_mutex); 3557 static DEFINE_MUTEX(disks_mutex);
@@ -4033,13 +4043,9 @@ static int do_md_stop(mddev_t * mddev, int mode, int is_open)
4033 mddev->queue->merge_bvec_fn = NULL; 4043 mddev->queue->merge_bvec_fn = NULL;
4034 mddev->queue->unplug_fn = NULL; 4044 mddev->queue->unplug_fn = NULL;
4035 mddev->queue->backing_dev_info.congested_fn = NULL; 4045 mddev->queue->backing_dev_info.congested_fn = NULL;
4036 if (mddev->pers->sync_request) {
4037 sysfs_remove_group(&mddev->kobj, &md_redundancy_group);
4038 if (mddev->sysfs_action)
4039 sysfs_put(mddev->sysfs_action);
4040 mddev->sysfs_action = NULL;
4041 }
4042 module_put(mddev->pers->owner); 4046 module_put(mddev->pers->owner);
4047 if (mddev->pers->sync_request)
4048 mddev->private = &md_redundancy_group;
4043 mddev->pers = NULL; 4049 mddev->pers = NULL;
4044 /* tell userspace to handle 'inactive' */ 4050 /* tell userspace to handle 'inactive' */
4045 sysfs_notify_dirent(mddev->sysfs_state); 4051 sysfs_notify_dirent(mddev->sysfs_state);