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.
/* 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.
+ */
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 (*sync_metadata)(struct active_array *a);
deactivate = 1;
}
if (a->curr_state == write_pending) {
- a->container->ss->mark_dirty(a);
+ a->container->ss->mark_clean(a, 0);
a->next_state = active;
}
if (a->curr_state == active_idle) {
/* Set array to 'clean' FIRST, then
- * a->ss->mark_clean(a);
+ * a->ss->mark_clean(a, ~0ULL);
* just ignore for now.
*/
}
if (a->resync_start == ~0ULL)
a->next_state = read_auto; /* array is clean */
else {
- a->container->ss->mark_dirty(a);
+ a->container->ss->mark_clean(a, 0);
a->next_state = active;
}
}
if (a->curr_action == idle &&
a->prev_action == resync) {
- /* check resync_start to see if it is 'max' */
- get_resync_start(a);
- a->container->ss->mark_sync(a, a->resync_start);
+ /* A resync has finished. The endpoint is recorded in
+ * 'sync_start'. We don't update the metadata
+ * until the array goes inactive or readonly though.
+ * Just check if we need to fiddle spares.
+ */
check_degraded = 1;
}
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)
{
fprintf(stderr, "ddf: open_new %d\n", inst);
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)
{
- fprintf(stderr, "ddf: mark clean %llu\n", sync_pos);
-}
-
-static void ddf_mark_dirty(struct active_array *a)
-{
- fprintf(stderr, "ddf: mark dirty\n");
-}
-
-static void ddf_mark_sync(struct active_array *a, unsigned long long resync)
-{
- fprintf(stderr, "ddf: mark sync\n");
+ 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
+ ddf->virt->entries[inst].state &= ~DDF_state_inconsistent;
}
static void ddf_set_disk(struct active_array *a, int n, int state)
.open_new = ddf_open_new,
.load_super = load_super_ddf,
.mark_clean = ddf_mark_clean,
- .mark_dirty = ddf_mark_dirty,
- .mark_sync = ddf_mark_sync,
.set_disk = ddf_set_disk,
.sync_metadata = ddf_sync_metadata,
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);
- if (dev->vol.dirty) {
- fprintf(stderr, "imsm: mark clean %llu\n", sync_pos);
- dev->vol.dirty = 0;
- super->updates_pending++;
- }
-}
+ if (dev->vol.dirty != dirty) {
+ fprintf(stderr, "imsm: mark 'clean' %llu\n", sync_pos);
-static void imsm_mark_dirty(struct active_array *a)
-{
- 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;
+ dev->vol.dirty = dirty;
super->updates_pending++;
}
}
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)
{
int inst = a->info.container_member;
.open_new = imsm_open_new,
.load_super = load_super_imsm,
.mark_clean = imsm_mark_clean,
- .mark_dirty = imsm_mark_dirty,
- .mark_sync = imsm_mark_sync,
.set_disk = imsm_set_disk,
.sync_metadata = imsm_sync_metadata,
};