From 4f0a7acc9a0a93d39b66b29e374f9a5edd173047 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 15 Jun 2010 18:41:57 -0700 Subject: [PATCH] mdmon: record sync_completed directly to the metadata When sync_action is idle mdmon takes the latest value of md/resync_start or md//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 --- monitor.c | 10 +++++++--- super-intel.c | 7 ++----- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/monitor.c b/monitor.c index 12f8d3e..59b4181 100644 --- a/monitor.c +++ b/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, diff --git a/super-intel.c b/super-intel.c index b88e6a9..3bd041a 100644 --- a/super-intel.c +++ b/super-intel.c @@ -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