From 2a0bb19e0089aef4fcc65513c40a54cb00e53a7b Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 15 May 2008 16:48:44 +1000 Subject: [PATCH] Flag arrays for deletion after they have been stopped. From: Dan Williams If they are later reassembled they will be replaced and deallocated via replace_array. Signed-off-by: Dan Williams --- managemon.c | 44 ++++++++++++++++++++++++++++++-------------- monitor.c | 16 ++++++++++++++-- 2 files changed, 44 insertions(+), 16 deletions(-) diff --git a/managemon.c b/managemon.c index 14e7184b..43c731fa 100644 --- a/managemon.c +++ b/managemon.c @@ -77,11 +77,26 @@ #include +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); } } diff --git a/monitor.c b/monitor.c index ee35bdf2..9e98aeb5 100644 --- 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; } -- 2.39.2