]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
mdmon: record sync_completed directly to the metadata
authorDan Williams <dan.j.williams@intel.com>
Wed, 16 Jun 2010 01:41:57 +0000 (18:41 -0700)
committerDan Williams <dan.j.williams@intel.com>
Wed, 16 Jun 2010 01:41:57 +0000 (18:41 -0700)
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>
monitor.c
super-intel.c

index 12f8d3e6237c8bef698b15dc7f884630f1dc110c..59b4181954c24c0dc209e93c17c6ba391e2a4eab 100644 (file)
--- 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,
index b88e6a9c6703e0e5f88858cb609edd5089ef3629..3bd041ad37c8a28014fdd847e9ff7785de30d321 100644 (file)
@@ -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