Make sure all changes to md/array_state are notified.
Changes in md/array_state could be of interest to a monitoring program. So make sure all changes trigger a notification. Exceptions: changing active_idle to active is not reported because it is frequent and not interesting. changing active to active_idle is only reported on arrays with externally managed metadata, as it is not interesting otherwise. Signed-off-by: Neil Brown <neilb@suse.de>
This commit is contained in:
@@ -236,6 +236,11 @@ All md devices contain:
|
|||||||
writing the word for the desired state, however some states
|
writing the word for the desired state, however some states
|
||||||
cannot be explicitly set, and some transitions are not allowed.
|
cannot be explicitly set, and some transitions are not allowed.
|
||||||
|
|
||||||
|
Select/poll works on this file. All changes except between
|
||||||
|
active_idle and active (which can be frequent and are not
|
||||||
|
very interesting) are notified. active->active_idle is
|
||||||
|
reported if the metadata is externally managed.
|
||||||
|
|
||||||
clear
|
clear
|
||||||
No devices, no size, no level
|
No devices, no size, no level
|
||||||
Writing is equivalent to STOP_ARRAY ioctl
|
Writing is equivalent to STOP_ARRAY ioctl
|
||||||
|
@@ -2716,8 +2716,10 @@ array_state_store(mddev_t *mddev, const char *buf, size_t len)
|
|||||||
}
|
}
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
else
|
else {
|
||||||
|
sysfs_notify(&mddev->kobj, NULL, "array_state");
|
||||||
return len;
|
return len;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
static struct md_sysfs_entry md_array_state =
|
static struct md_sysfs_entry md_array_state =
|
||||||
__ATTR(array_state, S_IRUGO|S_IWUSR, array_state_show, array_state_store);
|
__ATTR(array_state, S_IRUGO|S_IWUSR, array_state_show, array_state_store);
|
||||||
@@ -3408,7 +3410,11 @@ static void md_safemode_timeout(unsigned long data)
|
|||||||
{
|
{
|
||||||
mddev_t *mddev = (mddev_t *) data;
|
mddev_t *mddev = (mddev_t *) data;
|
||||||
|
|
||||||
mddev->safemode = 1;
|
if (!atomic_read(&mddev->writes_pending)) {
|
||||||
|
mddev->safemode = 1;
|
||||||
|
if (mddev->external)
|
||||||
|
sysfs_notify(&mddev->kobj, NULL, "array_state");
|
||||||
|
}
|
||||||
md_wakeup_thread(mddev->thread);
|
md_wakeup_thread(mddev->thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3675,6 +3681,7 @@ static int do_md_run(mddev_t * mddev)
|
|||||||
|
|
||||||
mddev->changed = 1;
|
mddev->changed = 1;
|
||||||
md_new_event(mddev);
|
md_new_event(mddev);
|
||||||
|
sysfs_notify(&mddev->kobj, NULL, "array_state");
|
||||||
kobject_uevent(&mddev->gendisk->dev.kobj, KOBJ_CHANGE);
|
kobject_uevent(&mddev->gendisk->dev.kobj, KOBJ_CHANGE);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -3709,6 +3716,8 @@ static int restart_array(mddev_t *mddev)
|
|||||||
md_wakeup_thread(mddev->thread);
|
md_wakeup_thread(mddev->thread);
|
||||||
md_wakeup_thread(mddev->sync_thread);
|
md_wakeup_thread(mddev->sync_thread);
|
||||||
err = 0;
|
err = 0;
|
||||||
|
sysfs_notify(&mddev->kobj, NULL, "array_state");
|
||||||
|
|
||||||
} else
|
} else
|
||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
|
|
||||||
@@ -3879,6 +3888,7 @@ static int do_md_stop(mddev_t * mddev, int mode)
|
|||||||
mdname(mddev));
|
mdname(mddev));
|
||||||
err = 0;
|
err = 0;
|
||||||
md_new_event(mddev);
|
md_new_event(mddev);
|
||||||
|
sysfs_notify(&mddev->kobj, NULL, "array_state");
|
||||||
out:
|
out:
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -4876,8 +4886,9 @@ static int md_ioctl(struct inode *inode, struct file *file,
|
|||||||
mddev->ro && mddev->pers) {
|
mddev->ro && mddev->pers) {
|
||||||
if (mddev->ro == 2) {
|
if (mddev->ro == 2) {
|
||||||
mddev->ro = 0;
|
mddev->ro = 0;
|
||||||
set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
|
sysfs_notify(&mddev->kobj, NULL, "array_state");
|
||||||
md_wakeup_thread(mddev->thread);
|
set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
|
||||||
|
md_wakeup_thread(mddev->thread);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
err = -EROFS;
|
err = -EROFS;
|
||||||
@@ -5516,6 +5527,7 @@ void md_done_sync(mddev_t *mddev, int blocks, int ok)
|
|||||||
*/
|
*/
|
||||||
void md_write_start(mddev_t *mddev, struct bio *bi)
|
void md_write_start(mddev_t *mddev, struct bio *bi)
|
||||||
{
|
{
|
||||||
|
int did_change = 0;
|
||||||
if (bio_data_dir(bi) != WRITE)
|
if (bio_data_dir(bi) != WRITE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -5526,6 +5538,7 @@ void md_write_start(mddev_t *mddev, struct bio *bi)
|
|||||||
set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
|
set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
|
||||||
md_wakeup_thread(mddev->thread);
|
md_wakeup_thread(mddev->thread);
|
||||||
md_wakeup_thread(mddev->sync_thread);
|
md_wakeup_thread(mddev->sync_thread);
|
||||||
|
did_change = 1;
|
||||||
}
|
}
|
||||||
atomic_inc(&mddev->writes_pending);
|
atomic_inc(&mddev->writes_pending);
|
||||||
if (mddev->safemode == 1)
|
if (mddev->safemode == 1)
|
||||||
@@ -5536,10 +5549,12 @@ void md_write_start(mddev_t *mddev, struct bio *bi)
|
|||||||
mddev->in_sync = 0;
|
mddev->in_sync = 0;
|
||||||
set_bit(MD_CHANGE_CLEAN, &mddev->flags);
|
set_bit(MD_CHANGE_CLEAN, &mddev->flags);
|
||||||
md_wakeup_thread(mddev->thread);
|
md_wakeup_thread(mddev->thread);
|
||||||
|
did_change = 1;
|
||||||
}
|
}
|
||||||
spin_unlock_irq(&mddev->write_lock);
|
spin_unlock_irq(&mddev->write_lock);
|
||||||
sysfs_notify(&mddev->kobj, NULL, "array_state");
|
|
||||||
}
|
}
|
||||||
|
if (did_change)
|
||||||
|
sysfs_notify(&mddev->kobj, NULL, "array_state");
|
||||||
wait_event(mddev->sb_wait,
|
wait_event(mddev->sb_wait,
|
||||||
!test_bit(MD_CHANGE_CLEAN, &mddev->flags) &&
|
!test_bit(MD_CHANGE_CLEAN, &mddev->flags) &&
|
||||||
!test_bit(MD_CHANGE_PENDING, &mddev->flags));
|
!test_bit(MD_CHANGE_PENDING, &mddev->flags));
|
||||||
@@ -5991,18 +6006,22 @@ void md_check_recovery(mddev_t *mddev)
|
|||||||
int spares = 0;
|
int spares = 0;
|
||||||
|
|
||||||
if (!mddev->external) {
|
if (!mddev->external) {
|
||||||
|
int did_change = 0;
|
||||||
spin_lock_irq(&mddev->write_lock);
|
spin_lock_irq(&mddev->write_lock);
|
||||||
if (mddev->safemode &&
|
if (mddev->safemode &&
|
||||||
!atomic_read(&mddev->writes_pending) &&
|
!atomic_read(&mddev->writes_pending) &&
|
||||||
!mddev->in_sync &&
|
!mddev->in_sync &&
|
||||||
mddev->recovery_cp == MaxSector) {
|
mddev->recovery_cp == MaxSector) {
|
||||||
mddev->in_sync = 1;
|
mddev->in_sync = 1;
|
||||||
|
did_change = 1;
|
||||||
if (mddev->persistent)
|
if (mddev->persistent)
|
||||||
set_bit(MD_CHANGE_CLEAN, &mddev->flags);
|
set_bit(MD_CHANGE_CLEAN, &mddev->flags);
|
||||||
}
|
}
|
||||||
if (mddev->safemode == 1)
|
if (mddev->safemode == 1)
|
||||||
mddev->safemode = 0;
|
mddev->safemode = 0;
|
||||||
spin_unlock_irq(&mddev->write_lock);
|
spin_unlock_irq(&mddev->write_lock);
|
||||||
|
if (did_change)
|
||||||
|
sysfs_notify(&mddev->kobj, NULL, "array_state");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mddev->flags)
|
if (mddev->flags)
|
||||||
|
Reference in New Issue
Block a user