Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 208384
b: refs/heads/master
c: bb4f1e9
h: refs/heads/master
v: v3
  • Loading branch information
NeilBrown committed Aug 8, 2010
1 parent 1622465 commit 8a3e323
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 15 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 147e0b6a639ac581ca3bf627bedc3f4a6d3eca66
refs/heads/master: bb4f1e9d0e2ef93de8e36ca0f5f26625fcd70b7d
31 changes: 17 additions & 14 deletions trunk/drivers/md/md.c
Original file line number Diff line number Diff line change
Expand Up @@ -580,13 +580,17 @@ static void mddev_unlock(mddev_t * mddev)
* an access to the files will try to take reconfig_mutex
* while holding the file unremovable, which leads to
* a deadlock.
* So hold open_mutex instead - we are allowed to take
* it while holding reconfig_mutex, and md_run can
* use it to wait for the remove to complete.
* So hold set sysfs_active while the remove in happeing,
* and anything else which might set ->to_remove or my
* otherwise change the sysfs namespace will fail with
* -EBUSY if sysfs_active is still set.
* We set sysfs_active under reconfig_mutex and elsewhere
* test it under the same mutex to ensure its correct value
* is seen.
*/
struct attribute_group *to_remove = mddev->to_remove;
mddev->to_remove = NULL;
mutex_lock(&mddev->open_mutex);
mddev->sysfs_active = 1;
mutex_unlock(&mddev->reconfig_mutex);

if (mddev->kobj.sd) {
Expand All @@ -600,7 +604,7 @@ static void mddev_unlock(mddev_t * mddev)
mddev->sysfs_action = NULL;
}
}
mutex_unlock(&mddev->open_mutex);
mddev->sysfs_active = 0;
} else
mutex_unlock(&mddev->reconfig_mutex);

Expand Down Expand Up @@ -3008,7 +3012,9 @@ level_store(mddev_t *mddev, const char *buf, size_t len)
* - new personality will access other array.
*/

if (mddev->sync_thread || mddev->reshape_position != MaxSector)
if (mddev->sync_thread ||
mddev->reshape_position != MaxSector ||
mddev->sysfs_active)
return -EBUSY;

if (!mddev->pers->quiesce) {
Expand Down Expand Up @@ -4393,13 +4399,9 @@ int md_run(mddev_t *mddev)

if (mddev->pers)
return -EBUSY;

/* These two calls synchronise us with the
* sysfs_remove_group calls in mddev_unlock,
* so they must have completed.
*/
mutex_lock(&mddev->open_mutex);
mutex_unlock(&mddev->open_mutex);
/* Cannot run until previous stop completes properly */
if (mddev->sysfs_active)
return -EBUSY;

/*
* Analyze all RAID superblock(s)
Expand Down Expand Up @@ -4770,7 +4772,8 @@ static int do_md_stop(mddev_t * mddev, int mode, int is_open)
mdk_rdev_t *rdev;

mutex_lock(&mddev->open_mutex);
if (atomic_read(&mddev->openers) > is_open) {
if (atomic_read(&mddev->openers) > is_open ||
mddev->sysfs_active) {
printk("md: %s still in use.\n",mdname(mddev));
err = -EBUSY;
} else if (mddev->pers) {
Expand Down
4 changes: 4 additions & 0 deletions trunk/drivers/md/md.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,10 @@ struct mddev_s
int suspended;
atomic_t active_io;
int ro;
int sysfs_active; /* set when sysfs deletes
* are happening, so run/
* takeover/stop are not safe
*/

struct gendisk *gendisk;

Expand Down

0 comments on commit 8a3e323

Please sign in to comment.