]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - super-intel.c
imsm: add the ddf field
[thirdparty/mdadm.git] / super-intel.c
index 266d734d0c15432a49a9ba1bb2b4c57e043349bd..300c7b86f6c261052f393b6b3b2b092e79860eac 100644 (file)
@@ -53,6 +53,7 @@
 
 #define MPB_SECTOR_CNT 418
 #define IMSM_RESERVED_SECTORS 4096
+#define SECT_PER_MB_SHIFT 11
 
 /* Disk configuration info. */
 #define IMSM_MAX_DEVICES 255
@@ -88,7 +89,7 @@ struct imsm_map {
        __u8  num_members;      /* number of member disks */
        __u8  num_domains;      /* number of parity domains */
        __u8  failed_disk_num;  /* valid only when state is degraded */
-       __u8  reserved[1];
+       __u8  ddf;
        __u32 filler[7];        /* expansion area */
 #define IMSM_ORD_REBUILD (1 << 24)
        __u32 disk_ord_tbl[1];  /* disk_ord_tbl[num_members],
@@ -1203,6 +1204,9 @@ static void getinfo_super_imsm_volume(struct supertype *st, struct mdinfo *info)
        info->array.utime         = 0;
        info->array.chunk_size    = __le16_to_cpu(map->blocks_per_strip) << 9;
        info->array.state         = !dev->vol.dirty;
+       info->custom_array_size   = __le32_to_cpu(dev->size_high);
+       info->custom_array_size   <<= 32;
+       info->custom_array_size   |= __le32_to_cpu(dev->size_low);
 
        info->disk.major = 0;
        info->disk.minor = 0;
@@ -1218,7 +1222,8 @@ static void getinfo_super_imsm_volume(struct supertype *st, struct mdinfo *info)
        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);
+               /* FIXME add curr_migr_unit to resync_start conversion */
+               info->resync_start = 0;
        else
                info->resync_start = ~0ULL;
 
@@ -2373,6 +2378,9 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info,
                array_blocks = calc_array_size(info->level, info->raid_disks,
                                               info->layout, info->chunk_size,
                                               info->size*2);
+       /* round array size down to closest MB */
+       array_blocks = (array_blocks >> SECT_PER_MB_SHIFT) << SECT_PER_MB_SHIFT;
+
        dev->size_low = __cpu_to_le32((__u32) array_blocks);
        dev->size_high = __cpu_to_le32((__u32) (array_blocks >> 32));
        dev->status = __cpu_to_le32(0);
@@ -2389,6 +2397,7 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info,
        map->failed_disk_num = ~0;
        map->map_state = info->level ? IMSM_T_STATE_UNINITIALIZED :
                                       IMSM_T_STATE_NORMAL;
+       map->ddf = 1;
 
        if (info->level == 1 && info->raid_disks > 2) {
                fprintf(stderr, Name": imsm does not support more than 2 disks"
@@ -3355,6 +3364,18 @@ static struct mdinfo *container_content_imsm(struct supertype *st)
                struct mdinfo *this;
                int slot;
 
+               /* do not publish arrays that are in the middle of an
+                * unsupported migration
+                */
+               if (dev->vol.migr_state &&
+                   (migr_type(dev) == MIGR_GEN_MIGR ||
+                    migr_type(dev) == MIGR_STATE_CHANGE)) {
+                       fprintf(stderr, Name ": cannot assemble volume '%.16s':"
+                               " unsupported migration in progress\n",
+                               dev->volume);
+                       continue;
+               }
+
                this = malloc(sizeof(*this));
                memset(this, 0, sizeof(*this));
                this->next = rest;
@@ -3401,7 +3422,7 @@ static struct mdinfo *container_content_imsm(struct supertype *st)
                        info_d = malloc(sizeof(*info_d));
                        if (!info_d) {
                                fprintf(stderr, Name ": failed to allocate disk"
-                                       " for volume %s\n", (char *) dev->volume);
+                                       " for volume %.16s\n", dev->volume);
                                free(this);
                                this = rest;
                                break;
@@ -3672,13 +3693,7 @@ static int imsm_set_array_state(struct active_array *a, int consistent)
                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++;
-       }
+        /* FIXME check if we can update curr_migr_unit from resync_start */
 
        /* mark dirty / clean */
        if (dev->vol.dirty != !consistent) {