} __attribute__ ((packed));
struct imsm_vol {
- __u32 reserved[2];
+ __u32 curr_migr_unit;
+ __u32 reserved;
__u8 migr_state; /* Normal or Migrating */
__u8 migr_type; /* Initializing, Rebuilding, ... */
__u8 dirty;
info->component_size = __le32_to_cpu(map->blocks_per_member);
memset(info->uuid, 0, sizeof(info->uuid));
- if (map->map_state == IMSM_T_STATE_UNINITIALIZED ||
- dev->vol.dirty || dev->vol.migr_state)
+ if (map->map_state == IMSM_T_STATE_UNINITIALIZED || dev->vol.dirty)
info->resync_start = 0;
+ else if (dev->vol.migr_state)
+ info->resync_start = __le32_to_cpu(dev->vol.curr_migr_unit);
else
info->resync_start = ~0ULL;
dev->vol.migr_state = 1;
dev->vol.migr_type = rebuild_resync;
+ dev->vol.curr_migr_unit = 0;
dest = get_imsm_map(dev, 1);
memcpy(dest, src, sizeof_imsm_map(src));
src->map_state = to_state;
}
+
+static void end_migration(struct imsm_dev *dev, __u8 map_state)
+{
+ struct imsm_map *map = get_imsm_map(dev, 0);
+
+ dev->vol.migr_state = 0;
+ dev->vol.curr_migr_unit = 0;
+ map->map_state = map_state;
+}
#endif
static int parse_raid_devices(struct intel_super *super)
vol->migr_state = 0;
vol->migr_type = 0;
vol->dirty = 0;
+ vol->curr_migr_unit = 0;
for (i = 0; i < idx; i++) {
struct imsm_dev *prev = get_imsm_dev(super, i);
struct imsm_map *pmap = get_imsm_map(prev, 0);
*/
if (is_resyncing(dev)) {
dprintf("imsm: mark resync done\n");
- dev->vol.migr_state = 0;
- map->map_state = map_state;
+ end_migration(dev, map_state);
super->updates_pending++;
}
} else if (!is_resyncing(dev) && !failed) {
super->updates_pending++;
}
+ /* check if we can update the migration checkpoint */
+ if (dev->vol.migr_state &&
+ __le32_to_cpu(dev->vol.curr_migr_unit) != a->resync_start) {
+ dprintf("imsm: checkpoint migration (%llu)\n", a->resync_start);
+ dev->vol.curr_migr_unit = __cpu_to_le32(a->resync_start);
+ super->updates_pending++;
+ }
+
/* mark dirty / clean */
if (dev->vol.dirty != !consistent) {
dprintf("imsm: mark '%s' (%llu)\n",
/* check if recovery complete, newly degraded, or failed */
if (map_state == IMSM_T_STATE_NORMAL && is_rebuilding(dev)) {
- map->map_state = map_state;
- dev->vol.migr_state = 0;
+ end_migration(dev, map_state);
super->updates_pending++;
} else if (map_state == IMSM_T_STATE_DEGRADED &&
map->map_state != map_state &&
} else if (map_state == IMSM_T_STATE_FAILED &&
map->map_state != map_state) {
dprintf("imsm: mark failed\n");
- dev->vol.migr_state = 0;
- map->map_state = map_state;
+ end_migration(dev, map_state);
super->updates_pending++;
}
}