mdmon: record sync_completed directly to the metadata
When sync_action is idle mdmon takes the latest value of md/resync_start or md/<dev>/recovery_start to record the resync/rebuild checkpoint in the metadata. However, now that mdmon is reading sync_completed there is no longer a need to wait for, or force an idle event to take a checkpoint. Simply update the forward progress of ->last_checkpoint at every wakeup event and force it to be recorded at least every 1/16th array-size interval. It may be recorded more frequently if a ->set_array_state() event occurs. This also cleans up some confusion in handling the dual-rebuild case. If more than one spare has been activated the kernel starts the rebuild at the lowest recovery offset, so we do not need to worry about min_recovery_start(). Signed-off-by: Dan Williams <dan.j.williams@intel.com>
This commit is contained in:
parent
0d80bb2f97
commit
4f0a7acc9a
10
monitor.c
10
monitor.c
|
@ -334,10 +334,14 @@ static int read_and_act(struct active_array *a)
|
|||
*/
|
||||
if (sync_completed > a->last_checkpoint &&
|
||||
sync_completed - a->last_checkpoint > a->info.component_size >> 4 &&
|
||||
a->curr_action > reshape && a->next_action == bad_action) {
|
||||
a->curr_action > reshape) {
|
||||
/* A (non-reshape) sync_action has reached a checkpoint.
|
||||
* Record the updated position in the metadata
|
||||
*/
|
||||
a->last_checkpoint = sync_completed;
|
||||
a->container->ss->set_array_state(a, a->curr_state <= clean);
|
||||
} else if (sync_completed > a->last_checkpoint)
|
||||
a->last_checkpoint = sync_completed;
|
||||
a->next_action = idle;
|
||||
}
|
||||
|
||||
a->container->ss->sync_metadata(a->container);
|
||||
dprintf("%s(%d): state:%s action:%s next(", __func__, a->info.container_member,
|
||||
|
|
|
@ -4415,14 +4415,11 @@ static int imsm_set_array_state(struct active_array *a, int consistent)
|
|||
|
||||
/* check if we can update curr_migr_unit from resync_start, recovery_start */
|
||||
blocks_per_unit = blocks_per_migr_unit(dev);
|
||||
if (blocks_per_unit && failed <= 1) {
|
||||
if (blocks_per_unit) {
|
||||
__u32 units32;
|
||||
__u64 units;
|
||||
|
||||
if (migr_type(dev) == MIGR_REBUILD)
|
||||
units = min_recovery_start(&a->info) / blocks_per_unit;
|
||||
else
|
||||
units = a->info.resync_start / blocks_per_unit;
|
||||
units = a->last_checkpoint / blocks_per_unit;
|
||||
units32 = units;
|
||||
|
||||
/* check that we did not overflow 32-bits, and that
|
||||
|
|
Loading…
Reference in New Issue