aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeil Brown <neilb@notabene.brown>2008-06-27 18:31:44 -0400
committerNeil Brown <neilb@notabene.brown>2008-06-27 18:31:44 -0400
commit526647320e696f434647f38421a6ecf65b859c43 (patch)
treeaa6bf13e6aa766051ba32a8b64157f4adf9fcd3e
parenta99ac97113d5bc25ddc4d17f404c2024ac6c57f9 (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.txt10
-rw-r--r--drivers/md/md.c14
-rw-r--r--include/linux/raid/md_k.h3
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}
1891static struct rdev_sysfs_entry rdev_state = 1893static 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 */