Change mark_clean to set_array_state.
DDF needs more fine grained understanding of the array state.
This commit is contained in:
parent
77402e5105
commit
ed9d66aade
17
mdadm.h
17
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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
29
super-ddf.c
29
super-ddf.c
|
@ -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)
|
||||
ddf->virt->entries[inst].state |= DDF_state_inconsistent;
|
||||
else
|
||||
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].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,
|
||||
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue