]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - super-intel.c
Remove st->text_version in favour of info->text_version
[thirdparty/mdadm.git] / super-intel.c
index 7ffcff82a0a195da7875f839aa67f079c5954a11..69aef65301d06f288f3ad7717f126f1c69a328f5 100644 (file)
@@ -443,11 +443,17 @@ static void getinfo_super_imsm(struct supertype *st, struct mdinfo *info)
        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,
@@ -1063,6 +1069,10 @@ static struct mdinfo *container_content_imsm(struct supertype *st)
                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);
@@ -1124,28 +1134,18 @@ static int imsm_open_new(struct supertype *c, struct active_array *a, int inst)
        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++;
        }
 }
@@ -1227,33 +1227,48 @@ static int imsm_count_failed(struct imsm_super *mpb, struct imsm_map *map)
        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)
@@ -1347,14 +1362,11 @@ struct superswitch super_imsm = {
        .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,
 };
@@ -1386,7 +1398,6 @@ struct superswitch super_imsm_container = {
        .major          = 2000,
        .swapuuid       = 0,
        .external       = 1,
-       .text_version   = "imsm",
 };
 
 struct superswitch super_imsm_raid = {
@@ -1406,5 +1417,4 @@ struct superswitch super_imsm_raid = {
        .major          = 2001,
        .swapuuid       = 0,
        .external       = 2,
-       .text_version   = "imsm",
 };