diff --git a/mdadm.h b/mdadm.h index 80a6f92..3e47fea 100644 --- a/mdadm.h +++ b/mdadm.h @@ -526,12 +526,16 @@ extern struct superswitch { /* Tell the metadata handler the current state of the array. * This covers whether it is known to be consistent (no pending writes) - * when how far along a resync is known to have progressed + * and how far along a resync is known to have progressed * (in a->resync_start). * resync status is really irrelevant if the array is not consistent, * but some metadata (DDF!) have a place to record the distinction. + * If 'consistent' is '2', then the array can mark it dirty if a + * resync/recovery/whatever is required, or leave it clean if not. + * Return value is 0 dirty (not consistent) and 1 if clean. + * it is only really important if consistent is passed in as '2'. */ - void (*set_array_state)(struct active_array *a, int consistent); + int (*set_array_state)(struct active_array *a, int consistent); /* When the state of a device might have changed, we call set_disk to * tell the metadata what the current state is. diff --git a/monitor.c b/monitor.c index ffb4c9c..900cba3 100644 --- a/monitor.c +++ b/monitor.c @@ -243,18 +243,10 @@ static int read_and_act(struct active_array *a) * readonly ??? */ get_resync_start(a); - if (a->resync_start == ~0ULL) { + if (a->container->ss->set_array_state(a, 2)) a->next_state = read_auto; /* array is clean */ - /* give the metadata a chance to force active if - * we have some recovery to do. metadata sets - * resync_start to !MaxSector in this case - */ - a->container->ss->set_array_state(a, 1); - } - if (a->resync_start != ~0ULL) { - a->container->ss->set_array_state(a, 0); - a->next_state = active; - } + else + a->next_state = active; /* Now active for recovery etc */ } if (!deactivate && diff --git a/super-ddf.c b/super-ddf.c index 5d38750..e41afa6 100644 --- a/super-ddf.c +++ b/super-ddf.c @@ -2680,11 +2680,17 @@ static int ddf_open_new(struct supertype *c, struct active_array *a, char *inst) * For DDF, we need to clear the DDF_state_inconsistent bit in the * !global! virtual_disk.virtual_entry structure. */ -static void ddf_set_array_state(struct active_array *a, int consistent) +static int ddf_set_array_state(struct active_array *a, int consistent) { struct ddf_super *ddf = a->container->sb; int inst = a->info.container_member; int old = ddf->virt->entries[inst].state; + if (consistent == 2) { + /* Should check if a recovery should be started FIXME */ + consistent = 1; + if (a->resync_start != ~0ULL) + consistent = 0; + } if (consistent) ddf->virt->entries[inst].state &= ~DDF_state_inconsistent; else @@ -2705,6 +2711,7 @@ static void ddf_set_array_state(struct active_array *a, int consistent) dprintf("ddf mark %d %s %llu\n", inst, consistent?"clean":"dirty", a->resync_start); + return consistent; } /* diff --git a/super-intel.c b/super-intel.c index 49645c6..0b902ed 100644 --- a/super-intel.c +++ b/super-intel.c @@ -2203,7 +2203,7 @@ static int imsm_count_failed(struct intel_super *super, struct imsm_map *map) return failed; } -static void imsm_set_array_state(struct active_array *a, int consistent) +static int imsm_set_array_state(struct active_array *a, int consistent) { int inst = a->info.container_member; struct intel_super *super = a->container->sb; @@ -2219,6 +2219,8 @@ static void imsm_set_array_state(struct active_array *a, int consistent) if (consistent && !dev->vol.dirty && (dev->vol.migr_state || map_state != IMSM_T_STATE_NORMAL)) a->resync_start = 0ULL; + if (consistent == 2 && a->resync_start != ~0ULL) + consistent = 0; if (a->resync_start == ~0ULL) { /* complete recovery or initial resync */ @@ -2253,6 +2255,7 @@ static void imsm_set_array_state(struct active_array *a, int consistent) dev->vol.dirty = dirty; super->updates_pending++; } + return consistent; } static void imsm_set_disk(struct active_array *a, int n, int state)