aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2008-10-20 22:25:28 -0400
committerNeilBrown <neilb@suse.de>2008-10-20 22:25:28 -0400
commit3c0ee63a64a20351ed6c16ec797e1f8c850741ea (patch)
tree482b825a00356a2b7b605065ce1d6ebe87591eb5 /drivers/md
parentb62b75905d571c29262a6c38cf9e5f089c203871 (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')
-rw-r--r--drivers/md/md.c21
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}
1933static struct rdev_sysfs_entry rdev_state = 1936static 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
6224void md_wait_for_blocked_rdev(mdk_rdev_t *rdev, mddev_t *mddev) 6227void 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));