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:
parent
a99ac97113
commit
526647320e
@ -297,6 +297,10 @@ Each directory contains:
|
||||
writemostly - device will only be subject to read
|
||||
requests if there are no other options.
|
||||
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.
|
||||
This includes spares that are in the process
|
||||
of being recovered to
|
||||
@ -306,6 +310,12 @@ Each directory contains:
|
||||
Writing "remove" removes the device from the array.
|
||||
Writing "writemostly" sets 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
|
||||
An approximate count of read errors that have been detected on
|
||||
|
@ -1886,6 +1886,8 @@ state_store(mdk_rdev_t *rdev, const char *buf, size_t len)
|
||||
|
||||
err = 0;
|
||||
}
|
||||
if (!err)
|
||||
sysfs_notify(&rdev->kobj, NULL, "state");
|
||||
return err ? err : len;
|
||||
}
|
||||
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) {
|
||||
rdev->raid_disk = -1;
|
||||
return err;
|
||||
}
|
||||
} else
|
||||
sysfs_notify(&rdev->kobj, NULL, "state");
|
||||
sprintf(nm, "rd%d", rdev->raid_disk);
|
||||
if (sysfs_create_link(&rdev->mddev->kobj, &rdev->kobj, nm))
|
||||
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(WriteMostly, &rdev->flags);
|
||||
set_bit(In_sync, &rdev->flags);
|
||||
sysfs_notify(&rdev->kobj, NULL, "state");
|
||||
}
|
||||
return len;
|
||||
}
|
||||
@ -3525,6 +3529,7 @@ static int do_md_run(mddev_t * mddev)
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
sysfs_notify(&rdev->kobj, NULL, "state");
|
||||
}
|
||||
|
||||
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)
|
||||
export_rdev(rdev);
|
||||
else
|
||||
sysfs_notify(&rdev->kobj, NULL, "state");
|
||||
|
||||
md_update_sb(mddev, 1);
|
||||
if (mddev->degraded)
|
||||
@ -5115,6 +5122,7 @@ void md_error(mddev_t *mddev, mdk_rdev_t *rdev)
|
||||
mddev->pers->error_handler(mddev,rdev);
|
||||
if (mddev->degraded)
|
||||
set_bit(MD_RECOVERY_RECOVER, &mddev->recovery);
|
||||
set_bit(StateChanged, &rdev->flags);
|
||||
set_bit(MD_RECOVERY_INTR, &mddev->recovery);
|
||||
set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
|
||||
md_wakeup_thread(mddev->thread);
|
||||
@ -6037,6 +6045,10 @@ void md_check_recovery(mddev_t *mddev)
|
||||
if (mddev->flags)
|
||||
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) &&
|
||||
!test_bit(MD_RECOVERY_DONE, &mddev->recovery)) {
|
||||
|
@ -87,6 +87,9 @@ struct mdk_rdev_s
|
||||
#define Blocked 8 /* An error occured on an externally
|
||||
* managed array, don't allow writes
|
||||
* 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;
|
||||
|
||||
int desc_nr; /* descriptor index in the superblock */
|
||||
|
Loading…
Reference in New Issue
Block a user