info->disk.state |= s & FAILED_DISK ? (1 << MD_DISK_FAULTY) : 0;
info->disk.state |= s & USABLE_DISK ? (1 << MD_DISK_SYNC) : 0;
info->reshape_active = 0;
+
+ strcpy(info->text_version, "imsm");
}
static void getinfo_super_imsm_raid(struct supertype *st, struct mdinfo *info)
{
printf("%s\n", __FUNCTION__);
+
+ sprintf(info->text_version, "/%s/%d",
+ devnum2devname(st->container_dev),
+ info->container_member); // FIXME is this even set here?
}
static int update_super_imsm(struct supertype *st, struct mdinfo *info,
strncpy(this->name, (char *) dev->volume, MAX_RAID_SERIAL_LEN);
this->name[MAX_RAID_SERIAL_LEN] = 0;
+ sprintf(this->text_version, "/%s/%d",
+ devnum2devname(st->container_dev),
+ this->container_member);
+
memset(this->uuid, 0, sizeof(this->uuid));
sz = __le32_to_cpu(dev->size_high);
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 = !consistent || (a->resync_start != ~0ULL);
- if (dev->vol.dirty) {
- 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)
-{
- 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 != dirty) {
+ fprintf(stderr, "imsm: mark '%s' (%llu)\n",
+ dirty?"dirty":"clean", a->resync_start);
- 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)
+static void imsm_set_disk(struct active_array *a, int n, int state)
{
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;
+ struct imsm_disk *disk;
+ __u32 status;
+ int failed = 0;
+ int new_failure = 0;
+
+ if (n > map->num_members)
+ fprintf(stderr, "imsm: set_disk %d out of range 0..%d\n",
+ n, map->num_members - 1);
- if (resync != ~0ULL)
+ if (n < 0)
return;
- fprintf(stderr, "imsm: mark sync\n");
+ fprintf(stderr, "imsm: set_disk %d:%x\n", n, state);
- 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++;
+ disk = get_imsm_disk(super->mpb, get_imsm_disk_idx(map, n));
+
+ /* check if we have seen this failure before */
+ status = __le32_to_cpu(disk->status);
+ if ((state & DS_FAULTY) && !(status & FAILED_DISK)) {
+ status |= FAILED_DISK;
+ disk->status = __cpu_to_le32(status);
+ new_failure = 1;
}
-}
-static void imsm_set_disk(struct active_array *a, int n)
-{
- fprintf(stderr, "imsm: set_disk %d\n", n);
+ /**
+ * the number of failures have changed, count up 'failed' to determine
+ * degraded / failed status
+ */
+ if (new_failure && map->map_state != IMSM_T_STATE_FAILED)
+ failed = imsm_count_failed(super->mpb, map);
+
+ if (failed)
+ map->map_state = imsm_check_degraded(super->mpb, inst, failed);
+
+ if (new_failure)
+ super->updates_pending++;
}
static int store_imsm_mpb(int fd, struct intel_super *super)
.major = 2000,
.swapuuid = 0,
.external = 1,
- .text_version = "imsm",
/* for mdmon */
.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_array_state= imsm_set_array_state,
.set_disk = imsm_set_disk,
.sync_metadata = imsm_sync_metadata,
};
.major = 2000,
.swapuuid = 0,
.external = 1,
- .text_version = "imsm",
};
struct superswitch super_imsm_raid = {
.major = 2001,
.swapuuid = 0,
.external = 2,
- .text_version = "imsm",
};