]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
Implement mark_clean for ddf and remove mark_dirty and mark_sync
authorNeil Brown <neilb@suse.de>
Mon, 26 May 2008 23:18:38 +0000 (09:18 +1000)
committerNeil Brown <neilb@suse.de>
Mon, 26 May 2008 23:18:38 +0000 (09:18 +1000)
mark_dirty is just a special case of mark_clean - with sync_pos == 0.
mark_sync is not required.  We don't modify the metadata when sync
finishes.  Only when the array becomes non-writeable at which point we
use mark_clean to record how far the resync progressed.

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

diff --git a/mdadm.h b/mdadm.h
index 6bf0c6259ce4b17e0348d22b6b52be809de1ce41..9dacdc4df7cbe1a4e2922e455f75f00cf7d05419 100644 (file)
--- a/mdadm.h
+++ b/mdadm.h
@@ -411,9 +411,16 @@ 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.
+        */
        void (*mark_clean)(struct active_array *a, unsigned long long sync_pos);
-       void (*mark_dirty)(struct active_array *a);
-       void (*mark_sync)(struct active_array *a, unsigned long long resync);
        void (*set_disk)(struct active_array *a, int n, int state);
        void (*sync_metadata)(struct active_array *a);
 
index 5fbbc83393c72b75cb029fe0b17f0757ff5cf66d..a630c9370f4698d35244cb81b8aa7f74f629300c 100644 (file)
--- a/monitor.c
+++ b/monitor.c
@@ -250,12 +250,12 @@ static int read_and_act(struct active_array *a)
                deactivate = 1;
        }
        if (a->curr_state == write_pending) {
-               a->container->ss->mark_dirty(a);
+               a->container->ss->mark_clean(a, 0);
                a->next_state = active;
        }
        if (a->curr_state == active_idle) {
                /* Set array to 'clean' FIRST, then
-                * a->ss->mark_clean(a);
+                * a->ss->mark_clean(a, ~0ULL);
                 * just ignore for now.
                 */
        }
@@ -269,16 +269,18 @@ static int read_and_act(struct active_array *a)
                if (a->resync_start == ~0ULL)
                        a->next_state = read_auto; /* array is clean */
                else {
-                       a->container->ss->mark_dirty(a);
+                       a->container->ss->mark_clean(a, 0);
                        a->next_state = active;
                }
        }
 
        if (a->curr_action == idle &&
            a->prev_action == resync) {
-               /* check resync_start to see if it is 'max' */
-               get_resync_start(a);
-               a->container->ss->mark_sync(a, a->resync_start);
+               /* A resync has finished.  The endpoint is recorded in
+                * 'sync_start'.  We don't update the metadata
+                * until the array goes inactive or readonly though.
+                * Just check if we need to fiddle spares.
+                */
                check_degraded = 1;
        }
 
index 91c53dae143bfa44fcbaebaf458c8dce091ae750..9ca18eb123919e9610bf88ca437694ef2aac4cb9 100644 (file)
@@ -2447,25 +2447,35 @@ static int compare_super_ddf(struct supertype *st, struct supertype *tst)
        return 0;
 }
 
+/*
+ * A new array 'a' has been started which claims to be instance 'inst'
+ * within container 'c'.
+ * We need to confirm that the array matches the metadata in 'c' so
+ * that we don't corrupt any metadata.
+ */
 static int ddf_open_new(struct supertype *c, struct active_array *a, int inst)
 {
        fprintf(stderr, "ddf: open_new %d\n", inst);
        return 0;
 }
 
+/*
+ * 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
+ * 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)
 {
-       fprintf(stderr, "ddf: mark clean %llu\n", sync_pos);
-}
-
-static void ddf_mark_dirty(struct active_array *a)
-{
-       fprintf(stderr, "ddf: mark dirty\n");
-}
-
-static void ddf_mark_sync(struct active_array *a, unsigned long long resync)
-{
-       fprintf(stderr, "ddf: mark sync\n");
+       struct ddf_super *ddf = a->container->sb;
+       int inst = a->info.container_member;
+       if (sync_pos == ~0ULL)
+               ddf->virt->entries[inst].state |= DDF_state_inconsistent;
+       else
+               ddf->virt->entries[inst].state &= ~DDF_state_inconsistent;
 }
 
 static void ddf_set_disk(struct active_array *a, int n, int state)
@@ -2512,8 +2522,6 @@ struct superswitch super_ddf = {
        .open_new       = ddf_open_new,
        .load_super     = load_super_ddf,
        .mark_clean     = ddf_mark_clean,
-       .mark_dirty     = ddf_mark_dirty,
-       .mark_sync      = ddf_mark_sync,
        .set_disk       = ddf_set_disk,
        .sync_metadata  = ddf_sync_metadata,
 
index a72d0de4f136ab5bb3f5efe5a1d0d305212d56eb..b57e9b1c2b135cc8c93db7e855a662dd422b226f 100644 (file)
@@ -1129,23 +1129,12 @@ static void imsm_mark_clean(struct active_array *a, unsigned long long sync_pos)
        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);
 
-       if (dev->vol.dirty) {
-               fprintf(stderr, "imsm: mark clean %llu\n", sync_pos);
-               dev->vol.dirty = 0;
-               super->updates_pending++;
-       }
-}
+       if (dev->vol.dirty != dirty) {
+               fprintf(stderr, "imsm: mark 'clean' %llu\n", sync_pos);
 
-static void imsm_mark_dirty(struct active_array *a)
-{
-       int inst = a->info.container_member;
-       struct intel_super *super = a->container->sb;
-       struct imsm_dev *dev = get_imsm_dev(super->mpb, inst);
-
-       if (!dev->vol.dirty) {
-               fprintf(stderr, "imsm: mark dirty\n");
-               dev->vol.dirty = 1;
+               dev->vol.dirty = dirty;
                super->updates_pending++;
        }
 }
@@ -1227,30 +1216,6 @@ static int imsm_count_failed(struct imsm_super *mpb, struct imsm_map *map)
        return failed;
 }
 
-static void imsm_mark_sync(struct active_array *a, unsigned long long resync)
-{
-       int inst = a->info.container_member;
-       struct intel_super *super = a->container->sb;
-       struct imsm_dev *dev = get_imsm_dev(super->mpb, inst);
-       struct imsm_map *map = dev->vol.map;
-       int failed;
-       __u8 map_state;
-
-       if (resync != ~0ULL)
-               return;
-
-       fprintf(stderr, "imsm: mark sync\n");
-
-       failed = imsm_count_failed(super->mpb, map);
-       map_state = imsm_check_degraded(super->mpb, inst, failed);
-       if (!failed)
-               map_state = IMSM_T_STATE_NORMAL;
-       if (map->map_state != map_state) {
-               map->map_state = map_state;
-               super->updates_pending++;
-       }
-}
-
 static void imsm_set_disk(struct active_array *a, int n, int state)
 {
        int inst = a->info.container_member;
@@ -1392,8 +1357,6 @@ struct superswitch super_imsm = {
        .open_new       = imsm_open_new,
        .load_super     = load_super_imsm,
        .mark_clean     = imsm_mark_clean,
-       .mark_dirty     = imsm_mark_dirty,
-       .mark_sync      = imsm_mark_sync,
        .set_disk       = imsm_set_disk,
        .sync_metadata  = imsm_sync_metadata,
 };