diff options
author | NeilBrown <neilb@suse.de> | 2008-10-20 22:25:28 -0400 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2008-10-20 22:25:28 -0400 |
commit | 3c0ee63a64a20351ed6c16ec797e1f8c850741ea (patch) | |
tree | 482b825a00356a2b7b605065ce1d6ebe87591eb5 /drivers/md/md.c | |
parent | b62b75905d571c29262a6c38cf9e5f089c203871 (diff) |
md: use sysfs_notify_dirent to notify changes to md/dev-xxx/state
The 'state' file for a device reports, for example, when the device
has failed. Changes should be reported to userspace ASAP without
the possibility of blocking on low-memory. sysfs_notify does
have that possibility (as it takes a mutex which can be held
across a kmalloc) so use sysfs_notify_dirent instead.
Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'drivers/md/md.c')
-rw-r--r-- | drivers/md/md.c | 21 |
1 files changed, 12 insertions, 9 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c index feea72dc4b69..8b303477c77b 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -1462,6 +1462,8 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev) | |||
1462 | kobject_del(&rdev->kobj); | 1462 | kobject_del(&rdev->kobj); |
1463 | goto fail; | 1463 | goto fail; |
1464 | } | 1464 | } |
1465 | rdev->sysfs_state = sysfs_get_dirent(rdev->kobj.sd, "state"); | ||
1466 | |||
1465 | list_add_rcu(&rdev->same_set, &mddev->disks); | 1467 | list_add_rcu(&rdev->same_set, &mddev->disks); |
1466 | bd_claim_by_disk(rdev->bdev, rdev->bdev->bd_holder, mddev->gendisk); | 1468 | bd_claim_by_disk(rdev->bdev, rdev->bdev->bd_holder, mddev->gendisk); |
1467 | return 0; | 1469 | return 0; |
@@ -1491,7 +1493,8 @@ static void unbind_rdev_from_array(mdk_rdev_t * rdev) | |||
1491 | printk(KERN_INFO "md: unbind<%s>\n", bdevname(rdev->bdev,b)); | 1493 | printk(KERN_INFO "md: unbind<%s>\n", bdevname(rdev->bdev,b)); |
1492 | rdev->mddev = NULL; | 1494 | rdev->mddev = NULL; |
1493 | sysfs_remove_link(&rdev->kobj, "block"); | 1495 | sysfs_remove_link(&rdev->kobj, "block"); |
1494 | 1496 | sysfs_put(rdev->sysfs_state); | |
1497 | rdev->sysfs_state = NULL; | ||
1495 | /* We need to delay this, otherwise we can deadlock when | 1498 | /* We need to delay this, otherwise we can deadlock when |
1496 | * writing to 'remove' to "dev/state". We also need | 1499 | * writing to 'remove' to "dev/state". We also need |
1497 | * to delay it due to rcu usage. | 1500 | * to delay it due to rcu usage. |
@@ -1926,8 +1929,8 @@ state_store(mdk_rdev_t *rdev, const char *buf, size_t len) | |||
1926 | 1929 | ||
1927 | err = 0; | 1930 | err = 0; |
1928 | } | 1931 | } |
1929 | if (!err) | 1932 | if (!err && rdev->sysfs_state) |
1930 | sysfs_notify(&rdev->kobj, NULL, "state"); | 1933 | sysfs_notify_dirent(rdev->sysfs_state); |
1931 | return err ? err : len; | 1934 | return err ? err : len; |
1932 | } | 1935 | } |
1933 | static struct rdev_sysfs_entry rdev_state = | 1936 | static struct rdev_sysfs_entry rdev_state = |
@@ -2022,7 +2025,7 @@ slot_store(mdk_rdev_t *rdev, const char *buf, size_t len) | |||
2022 | rdev->raid_disk = -1; | 2025 | rdev->raid_disk = -1; |
2023 | return err; | 2026 | return err; |
2024 | } else | 2027 | } else |
2025 | sysfs_notify(&rdev->kobj, NULL, "state"); | 2028 | sysfs_notify_dirent(rdev->sysfs_state); |
2026 | sprintf(nm, "rd%d", rdev->raid_disk); | 2029 | sprintf(nm, "rd%d", rdev->raid_disk); |
2027 | if (sysfs_create_link(&rdev->mddev->kobj, &rdev->kobj, nm)) | 2030 | if (sysfs_create_link(&rdev->mddev->kobj, &rdev->kobj, nm)) |
2028 | printk(KERN_WARNING | 2031 | printk(KERN_WARNING |
@@ -2039,7 +2042,7 @@ slot_store(mdk_rdev_t *rdev, const char *buf, size_t len) | |||
2039 | clear_bit(Faulty, &rdev->flags); | 2042 | clear_bit(Faulty, &rdev->flags); |
2040 | clear_bit(WriteMostly, &rdev->flags); | 2043 | clear_bit(WriteMostly, &rdev->flags); |
2041 | set_bit(In_sync, &rdev->flags); | 2044 | set_bit(In_sync, &rdev->flags); |
2042 | sysfs_notify(&rdev->kobj, NULL, "state"); | 2045 | sysfs_notify_dirent(rdev->sysfs_state); |
2043 | } | 2046 | } |
2044 | return len; | 2047 | return len; |
2045 | } | 2048 | } |
@@ -3583,7 +3586,7 @@ static int do_md_run(mddev_t * mddev) | |||
3583 | return -EINVAL; | 3586 | return -EINVAL; |
3584 | } | 3587 | } |
3585 | } | 3588 | } |
3586 | sysfs_notify(&rdev->kobj, NULL, "state"); | 3589 | sysfs_notify_dirent(rdev->sysfs_state); |
3587 | } | 3590 | } |
3588 | 3591 | ||
3589 | md_probe(mddev->unit, NULL, NULL); | 3592 | md_probe(mddev->unit, NULL, NULL); |
@@ -4302,7 +4305,7 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info) | |||
4302 | if (err) | 4305 | if (err) |
4303 | export_rdev(rdev); | 4306 | export_rdev(rdev); |
4304 | else | 4307 | else |
4305 | sysfs_notify(&rdev->kobj, NULL, "state"); | 4308 | sysfs_notify_dirent(rdev->sysfs_state); |
4306 | 4309 | ||
4307 | md_update_sb(mddev, 1); | 4310 | md_update_sb(mddev, 1); |
4308 | if (mddev->degraded) | 4311 | if (mddev->degraded) |
@@ -6113,7 +6116,7 @@ void md_check_recovery(mddev_t *mddev) | |||
6113 | 6116 | ||
6114 | rdev_for_each(rdev, rtmp, mddev) | 6117 | rdev_for_each(rdev, rtmp, mddev) |
6115 | if (test_and_clear_bit(StateChanged, &rdev->flags)) | 6118 | if (test_and_clear_bit(StateChanged, &rdev->flags)) |
6116 | sysfs_notify(&rdev->kobj, NULL, "state"); | 6119 | sysfs_notify_dirent(rdev->sysfs_state); |
6117 | 6120 | ||
6118 | 6121 | ||
6119 | if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) && | 6122 | if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) && |
@@ -6223,7 +6226,7 @@ void md_check_recovery(mddev_t *mddev) | |||
6223 | 6226 | ||
6224 | void md_wait_for_blocked_rdev(mdk_rdev_t *rdev, mddev_t *mddev) | 6227 | void md_wait_for_blocked_rdev(mdk_rdev_t *rdev, mddev_t *mddev) |
6225 | { | 6228 | { |
6226 | sysfs_notify(&rdev->kobj, NULL, "state"); | 6229 | sysfs_notify_dirent(rdev->sysfs_state); |
6227 | wait_event_timeout(rdev->blocked_wait, | 6230 | wait_event_timeout(rdev->blocked_wait, |
6228 | !test_bit(Blocked, &rdev->flags), | 6231 | !test_bit(Blocked, &rdev->flags), |
6229 | msecs_to_jiffies(5000)); | 6232 | msecs_to_jiffies(5000)); |