aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/md.txt5
-rw-r--r--drivers/md/md.c29
2 files changed, 29 insertions, 5 deletions
diff --git a/Documentation/md.txt b/Documentation/md.txt
index a8b430627473..dca97ba4944a 100644
--- a/Documentation/md.txt
+++ b/Documentation/md.txt
@@ -236,6 +236,11 @@ All md devices contain:
236 writing the word for the desired state, however some states 236 writing the word for the desired state, however some states
237 cannot be explicitly set, and some transitions are not allowed. 237 cannot be explicitly set, and some transitions are not allowed.
238 238
239 Select/poll works on this file. All changes except between
240 active_idle and active (which can be frequent and are not
241 very interesting) are notified. active->active_idle is
242 reported if the metadata is externally managed.
243
239 clear 244 clear
240 No devices, no size, no level 245 No devices, no size, no level
241 Writing is equivalent to STOP_ARRAY ioctl 246 Writing is equivalent to STOP_ARRAY ioctl
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 1442761ac98e..5b9d4fe4e6e4 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -2716,8 +2716,10 @@ array_state_store(mddev_t *mddev, const char *buf, size_t len)
2716 } 2716 }
2717 if (err) 2717 if (err)
2718 return err; 2718 return err;
2719 else 2719 else {
2720 sysfs_notify(&mddev->kobj, NULL, "array_state");
2720 return len; 2721 return len;
2722 }
2721} 2723}
2722static struct md_sysfs_entry md_array_state = 2724static struct md_sysfs_entry md_array_state =
2723__ATTR(array_state, S_IRUGO|S_IWUSR, array_state_show, array_state_store); 2725__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)
3408{ 3410{
3409 mddev_t *mddev = (mddev_t *) data; 3411 mddev_t *mddev = (mddev_t *) data;
3410 3412
3411 mddev->safemode = 1; 3413 if (!atomic_read(&mddev->writes_pending)) {
3414 mddev->safemode = 1;
3415 if (mddev->external)
3416 sysfs_notify(&mddev->kobj, NULL, "array_state");
3417 }
3412 md_wakeup_thread(mddev->thread); 3418 md_wakeup_thread(mddev->thread);
3413} 3419}
3414 3420
@@ -3675,6 +3681,7 @@ static int do_md_run(mddev_t * mddev)
3675 3681
3676 mddev->changed = 1; 3682 mddev->changed = 1;
3677 md_new_event(mddev); 3683 md_new_event(mddev);
3684 sysfs_notify(&mddev->kobj, NULL, "array_state");
3678 kobject_uevent(&mddev->gendisk->dev.kobj, KOBJ_CHANGE); 3685 kobject_uevent(&mddev->gendisk->dev.kobj, KOBJ_CHANGE);
3679 return 0; 3686 return 0;
3680} 3687}
@@ -3709,6 +3716,8 @@ static int restart_array(mddev_t *mddev)
3709 md_wakeup_thread(mddev->thread); 3716 md_wakeup_thread(mddev->thread);
3710 md_wakeup_thread(mddev->sync_thread); 3717 md_wakeup_thread(mddev->sync_thread);
3711 err = 0; 3718 err = 0;
3719 sysfs_notify(&mddev->kobj, NULL, "array_state");
3720
3712 } else 3721 } else
3713 err = -EINVAL; 3722 err = -EINVAL;
3714 3723
@@ -3879,6 +3888,7 @@ static int do_md_stop(mddev_t * mddev, int mode)
3879 mdname(mddev)); 3888 mdname(mddev));
3880 err = 0; 3889 err = 0;
3881 md_new_event(mddev); 3890 md_new_event(mddev);
3891 sysfs_notify(&mddev->kobj, NULL, "array_state");
3882out: 3892out:
3883 return err; 3893 return err;
3884} 3894}
@@ -4876,8 +4886,9 @@ static int md_ioctl(struct inode *inode, struct file *file,
4876 mddev->ro && mddev->pers) { 4886 mddev->ro && mddev->pers) {
4877 if (mddev->ro == 2) { 4887 if (mddev->ro == 2) {
4878 mddev->ro = 0; 4888 mddev->ro = 0;
4879 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); 4889 sysfs_notify(&mddev->kobj, NULL, "array_state");
4880 md_wakeup_thread(mddev->thread); 4890 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
4891 md_wakeup_thread(mddev->thread);
4881 4892
4882 } else { 4893 } else {
4883 err = -EROFS; 4894 err = -EROFS;
@@ -5516,6 +5527,7 @@ void md_done_sync(mddev_t *mddev, int blocks, int ok)
5516 */ 5527 */
5517void md_write_start(mddev_t *mddev, struct bio *bi) 5528void md_write_start(mddev_t *mddev, struct bio *bi)
5518{ 5529{
5530 int did_change = 0;
5519 if (bio_data_dir(bi) != WRITE) 5531 if (bio_data_dir(bi) != WRITE)
5520 return; 5532 return;
5521 5533
@@ -5526,6 +5538,7 @@ void md_write_start(mddev_t *mddev, struct bio *bi)
5526 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); 5538 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
5527 md_wakeup_thread(mddev->thread); 5539 md_wakeup_thread(mddev->thread);
5528 md_wakeup_thread(mddev->sync_thread); 5540 md_wakeup_thread(mddev->sync_thread);
5541 did_change = 1;
5529 } 5542 }
5530 atomic_inc(&mddev->writes_pending); 5543 atomic_inc(&mddev->writes_pending);
5531 if (mddev->safemode == 1) 5544 if (mddev->safemode == 1)
@@ -5536,10 +5549,12 @@ void md_write_start(mddev_t *mddev, struct bio *bi)
5536 mddev->in_sync = 0; 5549 mddev->in_sync = 0;
5537 set_bit(MD_CHANGE_CLEAN, &mddev->flags); 5550 set_bit(MD_CHANGE_CLEAN, &mddev->flags);
5538 md_wakeup_thread(mddev->thread); 5551 md_wakeup_thread(mddev->thread);
5552 did_change = 1;
5539 } 5553 }
5540 spin_unlock_irq(&mddev->write_lock); 5554 spin_unlock_irq(&mddev->write_lock);
5541 sysfs_notify(&mddev->kobj, NULL, "array_state");
5542 } 5555 }
5556 if (did_change)
5557 sysfs_notify(&mddev->kobj, NULL, "array_state");
5543 wait_event(mddev->sb_wait, 5558 wait_event(mddev->sb_wait,
5544 !test_bit(MD_CHANGE_CLEAN, &mddev->flags) && 5559 !test_bit(MD_CHANGE_CLEAN, &mddev->flags) &&
5545 !test_bit(MD_CHANGE_PENDING, &mddev->flags)); 5560 !test_bit(MD_CHANGE_PENDING, &mddev->flags));
@@ -5991,18 +6006,22 @@ void md_check_recovery(mddev_t *mddev)
5991 int spares = 0; 6006 int spares = 0;
5992 6007
5993 if (!mddev->external) { 6008 if (!mddev->external) {
6009 int did_change = 0;
5994 spin_lock_irq(&mddev->write_lock); 6010 spin_lock_irq(&mddev->write_lock);
5995 if (mddev->safemode && 6011 if (mddev->safemode &&
5996 !atomic_read(&mddev->writes_pending) && 6012 !atomic_read(&mddev->writes_pending) &&
5997 !mddev->in_sync && 6013 !mddev->in_sync &&
5998 mddev->recovery_cp == MaxSector) { 6014 mddev->recovery_cp == MaxSector) {
5999 mddev->in_sync = 1; 6015 mddev->in_sync = 1;
6016 did_change = 1;
6000 if (mddev->persistent) 6017 if (mddev->persistent)
6001 set_bit(MD_CHANGE_CLEAN, &mddev->flags); 6018 set_bit(MD_CHANGE_CLEAN, &mddev->flags);
6002 } 6019 }
6003 if (mddev->safemode == 1) 6020 if (mddev->safemode == 1)
6004 mddev->safemode = 0; 6021 mddev->safemode = 0;
6005 spin_unlock_irq(&mddev->write_lock); 6022 spin_unlock_irq(&mddev->write_lock);
6023 if (did_change)
6024 sysfs_notify(&mddev->kobj, NULL, "array_state");
6006 } 6025 }
6007 6026
6008 if (mddev->flags) 6027 if (mddev->flags)