]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
Change mark_clean to set_array_state.
authorNeil Brown <neilb@suse.de>
Mon, 26 May 2008 23:18:54 +0000 (09:18 +1000)
committerNeil Brown <neilb@suse.de>
Mon, 26 May 2008 23:18:54 +0000 (09:18 +1000)
DDF needs more fine grained understanding of the array state.

mdadm.h
monitor.c
super-ddf.c
super-intel.c

diff --git a/mdadm.h b/mdadm.h
index bf7e2967de704c411b5ba6c654165c7e59a5995e..b6102aaa3acf4147446d46573184432989ce2e07 100644 (file)
--- 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.
index e14fd38a3c2f943f78b6828c940433029ab57cdb..4fe1cb0d761937f560a3c492cf3185b6d3eb38d9 100644 (file)
--- 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;
        }
 
index 1e9101719f5d4970e746392fcdc49c635cd42f98..c7dcc1ae1abe6749a27b01d93d9e8aa1791f7655 100644 (file)
@@ -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,
 
index b57e9b1c2b135cc8c93db7e855a662dd422b226f..edfcae89eac9626840b25d4accf73a416272a1ea 100644 (file)
@@ -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,
 };