Implement mark_clean for ddf and remove mark_dirty and mark_sync
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.
This commit is contained in:
parent
d52690acc4
commit
4e5528c6f7
11
mdadm.h
11
mdadm.h
|
@ -411,9 +411,16 @@ extern struct superswitch {
|
||||||
|
|
||||||
/* for mdmon */
|
/* for mdmon */
|
||||||
int (*open_new)(struct supertype *c, struct active_array *a, int inst);
|
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_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 (*set_disk)(struct active_array *a, int n, int state);
|
||||||
void (*sync_metadata)(struct active_array *a);
|
void (*sync_metadata)(struct active_array *a);
|
||||||
|
|
||||||
|
|
14
monitor.c
14
monitor.c
|
@ -250,12 +250,12 @@ static int read_and_act(struct active_array *a)
|
||||||
deactivate = 1;
|
deactivate = 1;
|
||||||
}
|
}
|
||||||
if (a->curr_state == write_pending) {
|
if (a->curr_state == write_pending) {
|
||||||
a->container->ss->mark_dirty(a);
|
a->container->ss->mark_clean(a, 0);
|
||||||
a->next_state = active;
|
a->next_state = active;
|
||||||
}
|
}
|
||||||
if (a->curr_state == active_idle) {
|
if (a->curr_state == active_idle) {
|
||||||
/* Set array to 'clean' FIRST, then
|
/* Set array to 'clean' FIRST, then
|
||||||
* a->ss->mark_clean(a);
|
* a->ss->mark_clean(a, ~0ULL);
|
||||||
* just ignore for now.
|
* just ignore for now.
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
@ -269,16 +269,18 @@ static int read_and_act(struct active_array *a)
|
||||||
if (a->resync_start == ~0ULL)
|
if (a->resync_start == ~0ULL)
|
||||||
a->next_state = read_auto; /* array is clean */
|
a->next_state = read_auto; /* array is clean */
|
||||||
else {
|
else {
|
||||||
a->container->ss->mark_dirty(a);
|
a->container->ss->mark_clean(a, 0);
|
||||||
a->next_state = active;
|
a->next_state = active;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (a->curr_action == idle &&
|
if (a->curr_action == idle &&
|
||||||
a->prev_action == resync) {
|
a->prev_action == resync) {
|
||||||
/* check resync_start to see if it is 'max' */
|
/* A resync has finished. The endpoint is recorded in
|
||||||
get_resync_start(a);
|
* 'sync_start'. We don't update the metadata
|
||||||
a->container->ss->mark_sync(a, a->resync_start);
|
* until the array goes inactive or readonly though.
|
||||||
|
* Just check if we need to fiddle spares.
|
||||||
|
*/
|
||||||
check_degraded = 1;
|
check_degraded = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
34
super-ddf.c
34
super-ddf.c
|
@ -2447,25 +2447,35 @@ static int compare_super_ddf(struct supertype *st, struct supertype *tst)
|
||||||
return 0;
|
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)
|
static int ddf_open_new(struct supertype *c, struct active_array *a, int inst)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "ddf: open_new %d\n", inst);
|
fprintf(stderr, "ddf: open_new %d\n", inst);
|
||||||
return 0;
|
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)
|
static void ddf_mark_clean(struct active_array *a, unsigned long long sync_pos)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "ddf: mark clean %llu\n", sync_pos);
|
struct ddf_super *ddf = a->container->sb;
|
||||||
}
|
int inst = a->info.container_member;
|
||||||
|
if (sync_pos == ~0ULL)
|
||||||
static void ddf_mark_dirty(struct active_array *a)
|
ddf->virt->entries[inst].state |= DDF_state_inconsistent;
|
||||||
{
|
else
|
||||||
fprintf(stderr, "ddf: mark dirty\n");
|
ddf->virt->entries[inst].state &= ~DDF_state_inconsistent;
|
||||||
}
|
|
||||||
|
|
||||||
static void ddf_mark_sync(struct active_array *a, unsigned long long resync)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "ddf: mark sync\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ddf_set_disk(struct active_array *a, int n, int state)
|
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,
|
.open_new = ddf_open_new,
|
||||||
.load_super = load_super_ddf,
|
.load_super = load_super_ddf,
|
||||||
.mark_clean = ddf_mark_clean,
|
.mark_clean = ddf_mark_clean,
|
||||||
.mark_dirty = ddf_mark_dirty,
|
|
||||||
.mark_sync = ddf_mark_sync,
|
|
||||||
.set_disk = ddf_set_disk,
|
.set_disk = ddf_set_disk,
|
||||||
.sync_metadata = ddf_sync_metadata,
|
.sync_metadata = ddf_sync_metadata,
|
||||||
|
|
||||||
|
|
|
@ -1129,23 +1129,12 @@ static void imsm_mark_clean(struct active_array *a, unsigned long long sync_pos)
|
||||||
int inst = a->info.container_member;
|
int inst = a->info.container_member;
|
||||||
struct intel_super *super = a->container->sb;
|
struct intel_super *super = a->container->sb;
|
||||||
struct imsm_dev *dev = get_imsm_dev(super->mpb, inst);
|
struct imsm_dev *dev = get_imsm_dev(super->mpb, inst);
|
||||||
|
int dirty = (sync_pos != ~0ULL);
|
||||||
|
|
||||||
if (dev->vol.dirty) {
|
if (dev->vol.dirty != dirty) {
|
||||||
fprintf(stderr, "imsm: mark clean %llu\n", sync_pos);
|
fprintf(stderr, "imsm: mark 'clean' %llu\n", sync_pos);
|
||||||
dev->vol.dirty = 0;
|
|
||||||
super->updates_pending++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void imsm_mark_dirty(struct active_array *a)
|
dev->vol.dirty = dirty;
|
||||||
{
|
|
||||||
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;
|
|
||||||
super->updates_pending++;
|
super->updates_pending++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1227,30 +1216,6 @@ static int imsm_count_failed(struct imsm_super *mpb, struct imsm_map *map)
|
||||||
return failed;
|
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)
|
static void imsm_set_disk(struct active_array *a, int n, int state)
|
||||||
{
|
{
|
||||||
int inst = a->info.container_member;
|
int inst = a->info.container_member;
|
||||||
|
@ -1392,8 +1357,6 @@ struct superswitch super_imsm = {
|
||||||
.open_new = imsm_open_new,
|
.open_new = imsm_open_new,
|
||||||
.load_super = load_super_imsm,
|
.load_super = load_super_imsm,
|
||||||
.mark_clean = imsm_mark_clean,
|
.mark_clean = imsm_mark_clean,
|
||||||
.mark_dirty = imsm_mark_dirty,
|
|
||||||
.mark_sync = imsm_mark_sync,
|
|
||||||
.set_disk = imsm_set_disk,
|
.set_disk = imsm_set_disk,
|
||||||
.sync_metadata = imsm_sync_metadata,
|
.sync_metadata = imsm_sync_metadata,
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue