Allow passing metadata update to the monitor.
Code in manager can now just call queue_metadata_update with a (freeable) buf holding the update, and it will get passed to the monitor and written out.
This commit is contained in:
parent
b228067720
commit
2e735d1982
41
managemon.c
41
managemon.c
|
@ -151,6 +151,45 @@ static void replace_array(struct supertype *container,
|
||||||
write_wakeup(container);
|
write_wakeup(container);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct metadata_update *update_queue = NULL;
|
||||||
|
struct metadata_update *update_queue_handled = NULL;
|
||||||
|
struct metadata_update *update_queue_pending = NULL;
|
||||||
|
|
||||||
|
void check_update_queue(struct supertype *container)
|
||||||
|
{
|
||||||
|
while (update_queue_handled) {
|
||||||
|
struct metadata_update *this = update_queue_handled;
|
||||||
|
update_queue_handled = this->next;
|
||||||
|
free(this->buf);
|
||||||
|
free(this);
|
||||||
|
}
|
||||||
|
if (update_queue == NULL &&
|
||||||
|
update_queue_pending) {
|
||||||
|
update_queue = update_queue_pending;
|
||||||
|
update_queue_pending = NULL;
|
||||||
|
write_wakeup(container);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void queue_metadata_update(struct metadata_update *mu)
|
||||||
|
{
|
||||||
|
struct metadata_update **qp;
|
||||||
|
|
||||||
|
qp = &update_queue_pending;
|
||||||
|
while (*qp)
|
||||||
|
qp = & ((*qp)->next);
|
||||||
|
*qp = mu;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wait_update_handled(void)
|
||||||
|
{
|
||||||
|
/* Wait for any pending update to be handled by monitor.
|
||||||
|
* i.e. wait until update_queue is NULL
|
||||||
|
*/
|
||||||
|
while (update_queue)
|
||||||
|
usleep(100 * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
static void manage_container(struct mdstat_ent *mdstat,
|
static void manage_container(struct mdstat_ent *mdstat,
|
||||||
struct supertype *container)
|
struct supertype *container)
|
||||||
{
|
{
|
||||||
|
@ -404,6 +443,8 @@ void do_manager(struct supertype *container)
|
||||||
|
|
||||||
remove_old();
|
remove_old();
|
||||||
|
|
||||||
|
check_update_queue(container);
|
||||||
|
|
||||||
manager_ready = 1;
|
manager_ready = 1;
|
||||||
sigprocmask(SIG_SETMASK, &block, &orig);
|
sigprocmask(SIG_SETMASK, &block, &orig);
|
||||||
if (woke == 0)
|
if (woke == 0)
|
||||||
|
|
5
mdadm.h
5
mdadm.h
|
@ -372,6 +372,7 @@ extern mapping_t r5layout[], pers[], modes[], faultylayout[];
|
||||||
extern char *map_dev(int major, int minor, int create);
|
extern char *map_dev(int major, int minor, int create);
|
||||||
|
|
||||||
struct active_array;
|
struct active_array;
|
||||||
|
struct metadata_update;
|
||||||
|
|
||||||
extern struct superswitch {
|
extern struct superswitch {
|
||||||
void (*examine_super)(struct supertype *st, char *homehost);
|
void (*examine_super)(struct supertype *st, char *homehost);
|
||||||
|
@ -433,7 +434,9 @@ extern struct superswitch {
|
||||||
* not in fact changed.
|
* not in fact changed.
|
||||||
*/
|
*/
|
||||||
void (*set_disk)(struct active_array *a, int n, int state);
|
void (*set_disk)(struct active_array *a, int n, int state);
|
||||||
void (*sync_metadata)(struct active_array *a);
|
void (*sync_metadata)(struct supertype *st);
|
||||||
|
void (*process_update)(struct supertype *st,
|
||||||
|
struct metadata_update *update);
|
||||||
|
|
||||||
|
|
||||||
int major;
|
int major;
|
||||||
|
|
19
mdmon.h
19
mdmon.h
|
@ -21,7 +21,24 @@ struct active_array {
|
||||||
unsigned long long resync_start;
|
unsigned long long resync_start;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Metadata updates are handled by the monitor thread,
|
||||||
|
* as it has exclusive access to the metadata.
|
||||||
|
* When the manager want to updates metadata, either
|
||||||
|
* for it's own reason (e.g. committing a spare) or
|
||||||
|
* on behalf of mdadm, it creates a metadata_update
|
||||||
|
* structure and queues it to the monitor.
|
||||||
|
* Updates are created and processed by code under the
|
||||||
|
* superswitch. All common code sees them as opaque
|
||||||
|
* blobs.
|
||||||
|
*/
|
||||||
|
struct metadata_update {
|
||||||
|
int len;
|
||||||
|
char *buf;
|
||||||
|
void *space; /* allocated space that monitor will use */
|
||||||
|
struct metadata_update *next;
|
||||||
|
};
|
||||||
|
extern struct metadata_update *update_queue, *update_queue_handled;
|
||||||
|
|
||||||
#define MD_MAJOR 9
|
#define MD_MAJOR 9
|
||||||
|
|
||||||
|
|
14
monitor.c
14
monitor.c
|
@ -299,7 +299,7 @@ static int read_and_act(struct active_array *a)
|
||||||
// FIXME;
|
// FIXME;
|
||||||
}
|
}
|
||||||
|
|
||||||
a->container->ss->sync_metadata(a);
|
a->container->ss->sync_metadata(a->container);
|
||||||
|
|
||||||
/* Effect state changes in the array */
|
/* Effect state changes in the array */
|
||||||
if (a->next_state != bad_word)
|
if (a->next_state != bad_word)
|
||||||
|
@ -492,6 +492,18 @@ static int wait_and_act(struct supertype *container, int pfd,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (update_queue) {
|
||||||
|
struct metadata_update *this;
|
||||||
|
|
||||||
|
for (this = update_queue; this ; this = this->next)
|
||||||
|
container->ss->process_update(container, this);
|
||||||
|
|
||||||
|
update_queue_handled = update_queue;
|
||||||
|
update_queue = NULL;
|
||||||
|
signal_manager();
|
||||||
|
container->ss->sync_metadata(container);
|
||||||
|
}
|
||||||
|
|
||||||
for (a = *aap; a ; a = a->next) {
|
for (a = *aap; a ; a = a->next) {
|
||||||
if (a->replaces && !discard_this) {
|
if (a->replaces && !discard_this) {
|
||||||
struct active_array **ap;
|
struct active_array **ap;
|
||||||
|
|
|
@ -2666,7 +2666,7 @@ static void ddf_set_disk(struct active_array *a, int n, int state)
|
||||||
fprintf(stderr, "ddf: set_disk %d\n", n);
|
fprintf(stderr, "ddf: set_disk %d\n", n);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ddf_sync_metadata(struct active_array *a)
|
static void ddf_sync_metadata(struct supertype *st)
|
||||||
{
|
{
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2676,7 +2676,7 @@ static void ddf_sync_metadata(struct active_array *a)
|
||||||
* but ddf is sufficiently weird that it probably always
|
* but ddf is sufficiently weird that it probably always
|
||||||
* changes global data ....
|
* changes global data ....
|
||||||
*/
|
*/
|
||||||
__write_init_super_ddf(a->container, 0);
|
__write_init_super_ddf(st, 0);
|
||||||
fprintf(stderr, "ddf: sync_metadata\n");
|
fprintf(stderr, "ddf: sync_metadata\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1307,9 +1307,9 @@ static int store_imsm_mpb(int fd, struct intel_super *super)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void imsm_sync_metadata(struct active_array *a)
|
static void imsm_sync_metadata(struct supertype *container)
|
||||||
{
|
{
|
||||||
struct intel_super *super = a->container->sb;
|
struct intel_super *super = container->sb;
|
||||||
struct imsm_super *mpb = super->mpb;
|
struct imsm_super *mpb = super->mpb;
|
||||||
struct dl *d;
|
struct dl *d;
|
||||||
__u32 generation;
|
__u32 generation;
|
||||||
|
|
Loading…
Reference in New Issue