+
+static int default_chunk_imsm(struct supertype *st)
+{
+ struct intel_super *super = st->sb;
+
+ if (!super->orom)
+ return 0;
+
+ return imsm_orom_default_chunk(super->orom);
+}
+
+static void handle_missing(struct intel_super *super, struct imsm_dev *dev);
+
+static int kill_subarray_imsm(struct supertype *st)
+{
+ /* remove the subarray currently referenced by ->current_vol */
+ __u8 i;
+ struct intel_dev **dp;
+ struct intel_super *super = st->sb;
+ __u8 current_vol = super->current_vol;
+ struct imsm_super *mpb = super->anchor;
+
+ if (super->current_vol < 0)
+ return 2;
+ super->current_vol = -1; /* invalidate subarray cursor */
+
+ /* block deletions that would change the uuid of active subarrays
+ *
+ * FIXME when immutable ids are available, but note that we'll
+ * also need to fixup the invalidated/active subarray indexes in
+ * mdstat
+ */
+ for (i = 0; i < mpb->num_raid_devs; i++) {
+ char subarray[4];
+
+ if (i < current_vol)
+ continue;
+ sprintf(subarray, "%u", i);
+ if (is_subarray_active(subarray, st->devname)) {
+ fprintf(stderr,
+ Name ": deleting subarray-%d would change the UUID of active subarray-%d, aborting\n",
+ current_vol, i);
+
+ return 2;
+ }
+ }
+
+ if (st->update_tail) {
+ struct imsm_update_kill_array *u = malloc(sizeof(*u));
+
+ if (!u)
+ return 2;
+ u->type = update_kill_array;
+ u->dev_idx = current_vol;
+ append_metadata_update(st, u, sizeof(*u));
+
+ return 0;
+ }
+
+ for (dp = &super->devlist; *dp;)
+ if ((*dp)->index == current_vol) {
+ *dp = (*dp)->next;
+ } else {
+ handle_missing(super, (*dp)->dev);
+ if ((*dp)->index > current_vol)
+ (*dp)->index--;
+ dp = &(*dp)->next;
+ }
+
+ /* no more raid devices, all active components are now spares,
+ * but of course failed are still failed
+ */
+ if (--mpb->num_raid_devs == 0) {
+ struct dl *d;
+
+ for (d = super->disks; d; d = d->next)
+ if (d->index > -2) {
+ d->index = -1;
+ d->disk.status = SPARE_DISK;
+ }
+ }
+
+ super->updates_pending++;
+
+ return 0;
+}
+
+static int update_subarray_imsm(struct supertype *st, char *update, mddev_ident_t ident)
+{
+ /* update the subarray currently referenced by ->current_vol */
+ struct intel_super *super = st->sb;
+ struct imsm_super *mpb = super->anchor;
+
+ if (super->current_vol < 0)
+ return 2;
+
+ if (strcmp(update, "name") == 0) {
+ char *name = ident->name;
+
+ if (is_subarray_active(st->subarray, st->devname)) {
+ fprintf(stderr,
+ Name ": Unable to update name of active subarray\n");
+ return 2;
+ }
+
+ if (!check_name(super, name, 0))
+ return 2;
+
+ if (st->update_tail) {
+ struct imsm_update_rename_array *u = malloc(sizeof(*u));
+
+ if (!u)
+ return 2;
+ u->type = update_rename_array;
+ u->dev_idx = super->current_vol;
+ snprintf((char *) u->name, MAX_RAID_SERIAL_LEN, "%s", name);
+ append_metadata_update(st, u, sizeof(*u));
+ } else {
+ struct imsm_dev *dev;
+ int i;
+
+ dev = get_imsm_dev(super, super->current_vol);
+ snprintf((char *) dev->volume, MAX_RAID_SERIAL_LEN, "%s", name);
+ for (i = 0; i < mpb->num_raid_devs; i++) {
+ dev = get_imsm_dev(super, i);
+ handle_missing(super, dev);
+ }
+ super->updates_pending++;
+ }
+ } else
+ return 2;
+
+ return 0;
+}