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>
This commit is contained in:
Neil Brown 2008-06-28 08:31:44 +10:00
parent a99ac97113
commit 526647320e
3 changed files with 26 additions and 1 deletions

View file

@ -297,6 +297,10 @@ Each directory contains:
writemostly - device will only be subject to read writemostly - device will only be subject to read
requests if there are no other options. requests if there are no other options.
This applies only to raid1 arrays. This applies only to raid1 arrays.
blocked - device has failed, metadata is "external",
and the failure hasn't been acknowledged yet.
Writes that would write to this device if
it were not faulty are blocked.
spare - device is working, but not a full member. spare - device is working, but not a full member.
This includes spares that are in the process This includes spares that are in the process
of being recovered to of being recovered to
@ -306,6 +310,12 @@ Each directory contains:
Writing "remove" removes the device from the array. Writing "remove" removes the device from the array.
Writing "writemostly" sets the writemostly flag. Writing "writemostly" sets the writemostly flag.
Writing "-writemostly" clears the writemostly flag. Writing "-writemostly" clears the writemostly flag.
Writing "blocked" sets the "blocked" flag.
Writing "-blocked" clear the "blocked" flag and allows writes
to complete.
This file responds to select/poll. Any change to 'faulty'
or 'blocked' causes an event.
errors errors
An approximate count of read errors that have been detected on An approximate count of read errors that have been detected on

View file

@ -1886,6 +1886,8 @@ state_store(mdk_rdev_t *rdev, const char *buf, size_t len)
err = 0; err = 0;
} }
if (!err)
sysfs_notify(&rdev->kobj, NULL, "state");
return err ? err : len; return err ? err : len;
} }
static struct rdev_sysfs_entry rdev_state = static struct rdev_sysfs_entry rdev_state =
@ -1979,7 +1981,8 @@ slot_store(mdk_rdev_t *rdev, const char *buf, size_t len)
if (err) { if (err) {
rdev->raid_disk = -1; rdev->raid_disk = -1;
return err; return err;
} } else
sysfs_notify(&rdev->kobj, NULL, "state");
sprintf(nm, "rd%d", rdev->raid_disk); sprintf(nm, "rd%d", rdev->raid_disk);
if (sysfs_create_link(&rdev->mddev->kobj, &rdev->kobj, nm)) if (sysfs_create_link(&rdev->mddev->kobj, &rdev->kobj, nm))
printk(KERN_WARNING printk(KERN_WARNING
@ -1996,6 +1999,7 @@ slot_store(mdk_rdev_t *rdev, const char *buf, size_t len)
clear_bit(Faulty, &rdev->flags); clear_bit(Faulty, &rdev->flags);
clear_bit(WriteMostly, &rdev->flags); clear_bit(WriteMostly, &rdev->flags);
set_bit(In_sync, &rdev->flags); set_bit(In_sync, &rdev->flags);
sysfs_notify(&rdev->kobj, NULL, "state");
} }
return len; return len;
} }
@ -3525,6 +3529,7 @@ static int do_md_run(mddev_t * mddev)
return -EINVAL; return -EINVAL;
} }
} }
sysfs_notify(&rdev->kobj, NULL, "state");
} }
md_probe(mddev->unit, NULL, NULL); md_probe(mddev->unit, NULL, NULL);
@ -4256,6 +4261,8 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info)
} }
if (err) if (err)
export_rdev(rdev); export_rdev(rdev);
else
sysfs_notify(&rdev->kobj, NULL, "state");
md_update_sb(mddev, 1); md_update_sb(mddev, 1);
if (mddev->degraded) if (mddev->degraded)
@ -5115,6 +5122,7 @@ void md_error(mddev_t *mddev, mdk_rdev_t *rdev)
mddev->pers->error_handler(mddev,rdev); mddev->pers->error_handler(mddev,rdev);
if (mddev->degraded) if (mddev->degraded)
set_bit(MD_RECOVERY_RECOVER, &mddev->recovery); set_bit(MD_RECOVERY_RECOVER, &mddev->recovery);
set_bit(StateChanged, &rdev->flags);
set_bit(MD_RECOVERY_INTR, &mddev->recovery); set_bit(MD_RECOVERY_INTR, &mddev->recovery);
set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
md_wakeup_thread(mddev->thread); md_wakeup_thread(mddev->thread);
@ -6037,6 +6045,10 @@ void md_check_recovery(mddev_t *mddev)
if (mddev->flags) if (mddev->flags)
md_update_sb(mddev, 0); md_update_sb(mddev, 0);
rdev_for_each(rdev, rtmp, mddev)
if (test_and_clear_bit(StateChanged, &rdev->flags))
sysfs_notify(&rdev->kobj, NULL, "state");
if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) && if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) &&
!test_bit(MD_RECOVERY_DONE, &mddev->recovery)) { !test_bit(MD_RECOVERY_DONE, &mddev->recovery)) {

View file

@ -87,6 +87,9 @@ struct mdk_rdev_s
#define Blocked 8 /* An error occured on an externally #define Blocked 8 /* An error occured on an externally
* managed array, don't allow writes * managed array, don't allow writes
* until it is cleared */ * until it is cleared */
#define StateChanged 9 /* Faulty or Blocked has changed during
* interrupt, so it needs to be
* notified by the thread */
wait_queue_head_t blocked_wait; wait_queue_head_t blocked_wait;
int desc_nr; /* descriptor index in the superblock */ int desc_nr; /* descriptor index in the superblock */