]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
Flag arrays for deletion after they have been stopped.
authorDan Williams <dan.j.williams@intel.com>
Thu, 15 May 2008 06:48:44 +0000 (16:48 +1000)
committerNeil Brown <neilb@suse.de>
Thu, 15 May 2008 06:48:44 +0000 (16:48 +1000)
From: Dan Williams <dan.j.williams@intel.com>

If they are later reassembled they will be replaced and deallocated
via replace_array.

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
managemon.c
monitor.c

index 14e7184b0359801dd5fd9b25b3c674011635d177..43c731fa819fe7054759d79ee0d72f93e0b9f893 100644 (file)
 #include       <sys/socket.h>
 
 
+static void close_aa(struct active_array *aa)
+{
+       struct mdinfo *d;
+
+       for (d = aa->info.devs; d; d = d->next)
+               close(d->state_fd);
+
+       close(aa->action_fd);
+       close(aa->info.state_fd);
+       close(aa->resync_start_fd);
+       close(aa->sync_pos_fd);
+}
+
 static void free_aa(struct active_array *aa)
 {
-       /* Note that this doesn't close fds, as they may be in used
-        * by a clone.  Use close_aa for that.
+       /* Note that this doesn't close fds if they are being used
+        * by a clone.  ->container will be set for a clone
         */
+       if (!aa->container)
+               close_aa(aa);
        while (aa->info.devs) {
                struct mdinfo *d = aa->info.devs;
                aa->info.devs = d->next;
@@ -90,6 +105,11 @@ static void free_aa(struct active_array *aa)
        free(aa);
 }
 
+static void write_wakeup(struct supertype *c)
+{
+       write(c->pipe[1], "PING", 4);
+}
+
 static void replace_array(struct supertype *container,
                          struct active_array *old,
                          struct active_array *new)
@@ -115,6 +135,7 @@ static void replace_array(struct supertype *container,
        new->replaces = old;
        new->next = container->arrays;
        container->arrays = new;
+       write_wakeup(container);
 }
 
 
@@ -158,13 +179,9 @@ static void manage_member(struct mdstat_ent *mdstat,
 
 }
 
-static void write_wakeup(struct supertype *c)
-{
-       write(c->pipe[1], "PING", 4);
-}
-
 static void manage_new(struct mdstat_ent *mdstat,
-                      struct supertype *container)
+                      struct supertype *container,
+                      struct active_array *victim)
 {
        /* A new array has appeared in this container.
         * Hopefully it is already recorded in the metadata.
@@ -200,7 +217,7 @@ static void manage_new(struct mdstat_ent *mdstat,
                 * Mark it to be ignored by setting container to NULL
                 */
                new->container = NULL;
-               replace_array(container, NULL, new);
+               replace_array(container, victim, new);
                return;
        }
 
@@ -240,11 +257,10 @@ static void manage_new(struct mdstat_ent *mdstat,
        if (container->ss->open_new(container, new, inst) < 0) {
                // FIXME close all those files
                new->container = NULL;
-               replace_array(container, NULL, new);
+               replace_array(container, victim, new);
                return;
        }
-       replace_array(container, NULL, new);
-       write_wakeup(container);
+       replace_array(container, victim, new);
        return;
 }
 
@@ -278,8 +294,8 @@ void manage(struct mdstat_ent *mdstat, struct active_array *aa,
                                break;
                        }
                }
-               if (a == NULL)
-                       manage_new(mdstat, container);
+               if (a == NULL || !a->container)
+                       manage_new(mdstat, container, a);
        }
 }
 
index ee35bdf2588f755dab2a907228142c5f5f7b14af..9e98aeb50c89b5c5b45964ff705ff9014730daf4 100644 (file)
--- a/monitor.c
+++ b/monitor.c
@@ -228,6 +228,7 @@ int read_dev_state(int fd)
 static int read_and_act(struct active_array *a)
 {
        int check_degraded;
+       int deactivate = 0;
        struct mdinfo *mdi;
 
        a->next_state = bad_word;
@@ -246,6 +247,7 @@ static int read_and_act(struct active_array *a)
                get_sync_pos(a);
                a->container->ss->mark_clean(a, a->sync_pos);
                a->next_state = clear;
+               deactivate = 1;
        }
        if (a->curr_state == write_pending) {
                a->container->ss->mark_dirty(a);
@@ -326,6 +328,9 @@ static int read_and_act(struct active_array *a)
                mdi->next_state = 0;
        }
 
+       if (deactivate)
+               a->container = NULL;
+
        return 1;
 }
 
@@ -342,6 +347,12 @@ static int wait_and_act(struct active_array *aa, int pfd, int nowait)
        for (a = aa ; a ; a = a->next) {
                struct mdinfo *mdi;
 
+               /* once an array has been deactivated only the manager
+                * thread can make us care about it again
+                */
+               if (!a->container)
+                       continue;
+
                add_fd(&rfds, &maxfd, a->info.state_fd);
                add_fd(&rfds, &maxfd, a->action_fd);
                for (mdi = a->info.devs ; mdi ; mdi = mdi->next)
@@ -362,7 +373,7 @@ static int wait_and_act(struct active_array *aa, int pfd, int nowait)
        }
 
        for (a = aa; a ; a = a->next) {
-               if (a->replaces) {
+               if (a->replaces && !discard_this) {
                        struct active_array **ap;
                        for (ap = &a->next; *ap && *ap != a->replaces;
                             ap = & (*ap)->next)
@@ -372,7 +383,8 @@ static int wait_and_act(struct active_array *aa, int pfd, int nowait)
                        discard_this = a->replaces;
                        a->replaces = NULL;
                }
-               rv += read_and_act(a);
+               if (a->container)
+                       rv += read_and_act(a);
        }
        return rv;
 }