diff options
author | Neil Brown <neilb@notabene.brown> | 2008-06-27 18:31:44 -0400 |
---|---|---|
committer | Neil Brown <neilb@notabene.brown> | 2008-06-27 18:31:44 -0400 |
commit | 526647320e696f434647f38421a6ecf65b859c43 (patch) | |
tree | aa6bf13e6aa766051ba32a8b64157f4adf9fcd3e | |
parent | a99ac97113d5bc25ddc4d17f404c2024ac6c57f9 (diff) |
Make sure all changes to md/dev-XX/state are notified
The important state change happens during an interrupt
in md_error. So just set a flag there and call sysfs_notify
later in process context.
Signed-off-by: Neil Brown <neilb@suse.de>
-rw-r--r-- | Documentation/md.txt | 10 | ||||
-rw-r--r-- | drivers/md/md.c | 14 | ||||
-rw-r--r-- | include/linux/raid/md_k.h | 3 |
3 files changed, 26 insertions, 1 deletions
diff --git a/Documentation/md.txt b/Documentation/md.txt index eb6e69e3732e..e06cc59437e4 100644 --- a/Documentation/md.txt +++ b/Documentation/md.txt | |||
@@ -297,6 +297,10 @@ Each directory contains: | |||
297 | writemostly - device will only be subject to read | 297 | writemostly - device will only be subject to read |
298 | requests if there are no other options. | 298 | requests if there are no other options. |
299 | This applies only to raid1 arrays. | 299 | This applies only to raid1 arrays. |
300 | blocked - device has failed, metadata is "external", | ||
301 | and the failure hasn't been acknowledged yet. | ||
302 | Writes that would write to this device if | ||
303 | it were not faulty are blocked. | ||
300 | spare - device is working, but not a full member. | 304 | spare - device is working, but not a full member. |
301 | This includes spares that are in the process | 305 | This includes spares that are in the process |
302 | of being recovered to | 306 | of being recovered to |
@@ -306,6 +310,12 @@ Each directory contains: | |||
306 | Writing "remove" removes the device from the array. | 310 | Writing "remove" removes the device from the array. |
307 | Writing "writemostly" sets the writemostly flag. | 311 | Writing "writemostly" sets the writemostly flag. |
308 | Writing "-writemostly" clears the writemostly flag. | 312 | Writing "-writemostly" clears the writemostly flag. |
313 | Writing "blocked" sets the "blocked" flag. | ||
314 | Writing "-blocked" clear the "blocked" flag and allows writes | ||
315 | to complete. | ||
316 | |||
317 | This file responds to select/poll. Any change to 'faulty' | ||
318 | or 'blocked' causes an event. | ||
309 | 319 | ||
310 | errors | 320 | errors |
311 | An approximate count of read errors that have been detected on | 321 | An approximate count of read errors that have been detected on |
diff --git a/drivers/md/md.c b/drivers/md/md.c index 60d4cad88c20..dc99d95a1b6d 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -1886,6 +1886,8 @@ state_store(mdk_rdev_t *rdev, const char *buf, size_t len) | |||
1886 | 1886 | ||
1887 | err = 0; | 1887 | err = 0; |
1888 | } | 1888 | } |
1889 | if (!err) | ||
1890 | sysfs_notify(&rdev->kobj, NULL, "state"); | ||
1889 | return err ? err : len; | 1891 | return err ? err : len; |
1890 | } | 1892 | } |
1891 | static struct rdev_sysfs_entry rdev_state = | 1893 | static struct rdev_sysfs_entry rdev_state = |
@@ -1979,7 +1981,8 @@ slot_store(mdk_rdev_t *rdev, const char *buf, size_t len) | |||
1979 | if (err) { | 1981 | if (err) { |
1980 | rdev->raid_disk = -1; | 1982 | rdev->raid_disk = -1; |
1981 | return err; | 1983 | return err; |
1982 | } | 1984 | } else |
1985 | sysfs_notify(&rdev->kobj, NULL, "state"); | ||
1983 | sprintf(nm, "rd%d", rdev->raid_disk); | 1986 | sprintf(nm, "rd%d", rdev->raid_disk); |
1984 | if (sysfs_create_link(&rdev->mddev->kobj, &rdev->kobj, nm)) | 1987 | if (sysfs_create_link(&rdev->mddev->kobj, &rdev->kobj, nm)) |
1985 | printk(KERN_WARNING | 1988 | printk(KERN_WARNING |
@@ -1996,6 +1999,7 @@ slot_store(mdk_rdev_t *rdev, const char *buf, size_t len) | |||
1996 | clear_bit(Faulty, &rdev->flags); | 1999 | clear_bit(Faulty, &rdev->flags); |
1997 | clear_bit(WriteMostly, &rdev->flags); | 2000 | clear_bit(WriteMostly, &rdev->flags); |
1998 | set_bit(In_sync, &rdev->flags); | 2001 | set_bit(In_sync, &rdev->flags); |
2002 | sysfs_notify(&rdev->kobj, NULL, "state"); | ||
1999 | } | 2003 | } |
2000 | return len; | 2004 | return len; |
2001 | } | 2005 | } |
@@ -3525,6 +3529,7 @@ static int do_md_run(mddev_t * mddev) | |||
3525 | return -EINVAL; | 3529 | return -EINVAL; |
3526 | } | 3530 | } |
3527 | } | 3531 | } |
3532 | sysfs_notify(&rdev->kobj, NULL, "state"); | ||
3528 | } | 3533 | } |
3529 | 3534 | ||
3530 | md_probe(mddev->unit, NULL, NULL); | 3535 | md_probe(mddev->unit, NULL, NULL); |
@@ -4256,6 +4261,8 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info) | |||
4256 | } | 4261 | } |
4257 | if (err) | 4262 | if (err) |
4258 | export_rdev(rdev); | 4263 | export_rdev(rdev); |
4264 | else | ||
4265 | sysfs_notify(&rdev->kobj, NULL, "state"); | ||
4259 | 4266 | ||
4260 | md_update_sb(mddev, 1); | 4267 | md_update_sb(mddev, 1); |
4261 | if (mddev->degraded) | 4268 | if (mddev->degraded) |
@@ -5115,6 +5122,7 @@ void md_error(mddev_t *mddev, mdk_rdev_t *rdev) | |||
5115 | mddev->pers->error_handler(mddev,rdev); | 5122 | mddev->pers->error_handler(mddev,rdev); |
5116 | if (mddev->degraded) | 5123 | if (mddev->degraded) |
5117 | set_bit(MD_RECOVERY_RECOVER, &mddev->recovery); | 5124 | set_bit(MD_RECOVERY_RECOVER, &mddev->recovery); |
5125 | set_bit(StateChanged, &rdev->flags); | ||
5118 | set_bit(MD_RECOVERY_INTR, &mddev->recovery); | 5126 | set_bit(MD_RECOVERY_INTR, &mddev->recovery); |
5119 | set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); | 5127 | set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); |
5120 | md_wakeup_thread(mddev->thread); | 5128 | md_wakeup_thread(mddev->thread); |
@@ -6037,6 +6045,10 @@ void md_check_recovery(mddev_t *mddev) | |||
6037 | if (mddev->flags) | 6045 | if (mddev->flags) |
6038 | md_update_sb(mddev, 0); | 6046 | md_update_sb(mddev, 0); |
6039 | 6047 | ||
6048 | rdev_for_each(rdev, rtmp, mddev) | ||
6049 | if (test_and_clear_bit(StateChanged, &rdev->flags)) | ||
6050 | sysfs_notify(&rdev->kobj, NULL, "state"); | ||
6051 | |||
6040 | 6052 | ||
6041 | if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) && | 6053 | if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) && |
6042 | !test_bit(MD_RECOVERY_DONE, &mddev->recovery)) { | 6054 | !test_bit(MD_RECOVERY_DONE, &mddev->recovery)) { |
diff --git a/include/linux/raid/md_k.h b/include/linux/raid/md_k.h index 62aa9c9a6ddc..df30c4395875 100644 --- a/include/linux/raid/md_k.h +++ b/include/linux/raid/md_k.h | |||
@@ -87,6 +87,9 @@ struct mdk_rdev_s | |||
87 | #define Blocked 8 /* An error occured on an externally | 87 | #define Blocked 8 /* An error occured on an externally |
88 | * managed array, don't allow writes | 88 | * managed array, don't allow writes |
89 | * until it is cleared */ | 89 | * until it is cleared */ |
90 | #define StateChanged 9 /* Faulty or Blocked has changed during | ||
91 | * interrupt, so it needs to be | ||
92 | * notified by the thread */ | ||
90 | wait_queue_head_t blocked_wait; | 93 | wait_queue_head_t blocked_wait; |
91 | 94 | ||
92 | int desc_nr; /* descriptor index in the superblock */ | 95 | int desc_nr; /* descriptor index in the superblock */ |