From ed9d66aadec7ae41751e3a95352628814b47fbad Mon Sep 17 00:00:00 2001 From: Neil Brown Date: Tue, 27 May 2008 09:18:54 +1000 Subject: [PATCH] Change mark_clean to set_array_state. DDF needs more fine grained understanding of the array state. --- mdadm.h | 17 ++++++++--------- monitor.c | 9 ++++++--- super-ddf.c | 27 ++++++++++++++++++++------- super-intel.c | 9 +++++---- 4 files changed, 39 insertions(+), 23 deletions(-) diff --git a/mdadm.h b/mdadm.h index bf7e2967..b6102aaa 100644 --- a/mdadm.h +++ b/mdadm.h @@ -411,16 +411,15 @@ extern struct superswitch { /* for mdmon */ int (*open_new)(struct supertype *c, struct active_array *a, int inst); - /* This tells the metadata handler that all data up to sync_pos is - * known to be insync, and will stay insync until told otherwise. - * All data beyond sync_pos may not be insync. - * If sync_pos == 0, this marks the array as 'dirty'. - * If sync_pos == ~0, this marks it as fully 'clean'. - * If other numbers cannot be stored, they should be treated as 0. - * mark_clean is always called with a sync_pos of 0 before any - * write to an array with redundancy is allowed. + + /* 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 + * (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. */ - void (*mark_clean)(struct active_array *a, unsigned long long sync_pos); + void (*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 e14fd38a..4fe1cb0d 100644 --- a/monitor.c +++ b/monitor.c @@ -232,12 +232,13 @@ static int read_and_act(struct active_array *a) if (a->curr_state <= inactive && a->prev_state > inactive) { /* array has been stopped */ - a->container->ss->mark_clean(a, a->resync_start); + a->container->ss->set_array_state(a, 1); a->next_state = clear; deactivate = 1; } if (a->curr_state == write_pending) { - a->container->ss->mark_clean(a, 0); + get_resync_start(a); + a->container->ss->set_array_state(a, 0); a->next_state = active; } if (a->curr_state == active_idle) { @@ -253,10 +254,11 @@ static int read_and_act(struct active_array *a) * readonly ??? */ get_resync_start(a); + printf("Found a readonly array at %llu\n", a->resync_start); if (a->resync_start == ~0ULL) a->next_state = read_auto; /* array is clean */ else { - a->container->ss->mark_clean(a, 0); + a->container->ss->set_array_state(a, 0); a->next_state = active; } } @@ -269,6 +271,7 @@ static int read_and_act(struct active_array *a) * Just check if we need to fiddle spares. */ get_resync_start(a); + a->container->ss->set_array_state(a, 0); check_degraded = 1; } diff --git a/super-ddf.c b/super-ddf.c index 1e910171..c7dcc1ae 100644 --- a/super-ddf.c +++ b/super-ddf.c @@ -2403,10 +2403,13 @@ static struct mdinfo *container_content_ddf(struct supertype *st) break; if ((ddf->virt->entries[i].state & DDF_state_inconsistent) || (ddf->virt->entries[i].init_state & DDF_initstate_mask) != - DDF_init_full) + DDF_init_full) { this->array.state = 0; - else + this->resync_start = 0; + } else { this->array.state = 1; + this->resync_start = ~0ULL; + } memcpy(this->name, ddf->virt->entries[i].name, 32); this->name[33]=0; @@ -2515,21 +2518,31 @@ static int ddf_open_new(struct supertype *c, struct active_array *a, int inst) /* * The array 'a' is to be marked clean in the metadata. - * If 'sync_pos' is not ~(unsigned long long)0, then the array is only + * If '->resync_start' is not ~(unsigned long long)0, then the array is only * clean up to the point (in sectors). If that cannot be recorded in the * metadata, then leave it as dirty. * * For DDF, we need to clear the DDF_state_inconsistent bit in the * !global! virtual_disk.virtual_entry structure. */ -static void ddf_mark_clean(struct active_array *a, unsigned long long sync_pos) +static void ddf_set_array_state(struct active_array *a, int consistent) { struct ddf_super *ddf = a->container->sb; int inst = a->info.container_member; - if (sync_pos == ~0ULL) + if (consistent) + ddf->virt->entries[inst].state &= ~DDF_state_inconsistent; + else ddf->virt->entries[inst].state |= DDF_state_inconsistent; + ddf->virt->entries[inst].init_state &= ~DDF_initstate_mask; + if (a->resync_start == ~0ULL) + ddf->virt->entries[inst].init_state |= DDF_init_full; + else if (a->resync_start == 0) + ddf->virt->entries[inst].init_state |= DDF_init_not; else - ddf->virt->entries[inst].state &= ~DDF_state_inconsistent; + ddf->virt->entries[inst].init_state |= DDF_init_quick; + + printf("ddf mark %s %llu\n", consistent?"clean":"dirty", + a->resync_start); } /* @@ -2671,7 +2684,7 @@ struct superswitch super_ddf = { /* for mdmon */ .open_new = ddf_open_new, - .mark_clean = ddf_mark_clean, + .set_array_state= ddf_set_array_state, .set_disk = ddf_set_disk, .sync_metadata = ddf_sync_metadata, diff --git a/super-intel.c b/super-intel.c index b57e9b1c..edfcae89 100644 --- a/super-intel.c +++ b/super-intel.c @@ -1124,15 +1124,16 @@ static int imsm_open_new(struct supertype *c, struct active_array *a, int inst) return 0; } -static void imsm_mark_clean(struct active_array *a, unsigned long long sync_pos) +static void imsm_set_array_state(struct active_array *a, int consistent) { int inst = a->info.container_member; struct intel_super *super = a->container->sb; struct imsm_dev *dev = get_imsm_dev(super->mpb, inst); - int dirty = (sync_pos != ~0ULL); + int dirty = !consistent || (a->resync_start != ~0ULL); if (dev->vol.dirty != dirty) { - fprintf(stderr, "imsm: mark 'clean' %llu\n", sync_pos); + fprintf(stderr, "imsm: mark '%s' (%llu)\n", + dirty?"dirty":"clean", a->resync_start); dev->vol.dirty = dirty; super->updates_pending++; @@ -1356,7 +1357,7 @@ struct superswitch super_imsm = { /* for mdmon */ .open_new = imsm_open_new, .load_super = load_super_imsm, - .mark_clean = imsm_mark_clean, + .set_array_state= imsm_set_array_state, .set_disk = imsm_set_disk, .sync_metadata = imsm_sync_metadata, }; -- 2.39.2