]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - super-intel.c
Retire mdassemble
[thirdparty/mdadm.git] / super-intel.c
index 87fec8bc0952ed3f0b4b10b593967413120fe7ac..0aed57c8e2c5b431d5b7fb873e2da4ecb6f6bc97 100644 (file)
@@ -260,9 +260,9 @@ struct bbm_log {
        struct bbm_log_entry marked_block_entries[BBM_LOG_MAX_ENTRIES];
 } __attribute__ ((__packed__));
 
-#ifndef MDASSEMBLE
 static char *map_state_str[] = { "normal", "uninitialized", "degraded", "failed" };
-#endif
+
+#define BLOCKS_PER_KB  (1024/512)
 
 #define RAID_DISK_RESERVED_BLOCKS_IMSM_HI 2209
 
@@ -451,6 +451,7 @@ enum imsm_update_type {
        update_general_migration_checkpoint,
        update_size_change,
        update_prealloc_badblocks_mem,
+       update_rwh_policy,
 };
 
 struct imsm_update_activate_spare {
@@ -543,6 +544,12 @@ struct imsm_update_prealloc_bb_mem {
        enum imsm_update_type type;
 };
 
+struct imsm_update_rwh_policy {
+       enum imsm_update_type type;
+       int new_policy;
+       int dev_idx;
+};
+
 static const char *_sys_dev_type[] = {
        [SYS_DEV_UNKNOWN] = "Unknown",
        [SYS_DEV_SAS] = "SAS",
@@ -663,12 +670,10 @@ static struct supertype *match_metadata_desc_imsm(char *arg)
        return st;
 }
 
-#ifndef MDASSEMBLE
 static __u8 *get_imsm_version(struct imsm_super *mpb)
 {
        return &mpb->sig[MPB_SIG_LEN];
 }
-#endif
 
 /* retrieve a disk directly from the anchor when the anchor is known to be
  * up-to-date, currently only at load time
@@ -775,7 +780,6 @@ static size_t sizeof_imsm_dev(struct imsm_dev *dev, int migr_state)
        return size;
 }
 
-#ifndef MDASSEMBLE
 /* retrieve disk serial number list from a metadata update */
 static struct disk_info *get_disk_info(struct imsm_update_create_array *update)
 {
@@ -787,7 +791,6 @@ static struct disk_info *get_disk_info(struct imsm_update_create_array *update)
 
        return inf;
 }
-#endif
 
 static struct imsm_dev *__get_imsm_dev(struct imsm_super *mpb, __u8 index)
 {
@@ -838,7 +841,6 @@ static inline struct bbm_log_block_addr __cpu_to_le48(unsigned long long sec)
        return addr;
 }
 
-#ifndef MDASSEMBLE
 /* get size of the bbm log */
 static __u32 get_imsm_bbm_log_size(struct bbm_log *log)
 {
@@ -969,7 +971,6 @@ static int clear_badblock(struct bbm_log *log, const __u8 idx, const unsigned
 
        return 1;
 }
-#endif /* MDASSEMBLE */
 
 /* allocate and load BBM log from metadata */
 static int load_bbm_log(struct intel_super *super)
@@ -1317,6 +1318,19 @@ static int is_journal(struct imsm_disk *disk)
        return (disk->status & JOURNAL_DISK) == JOURNAL_DISK;
 }
 
+/* round array size down to closest MB and ensure it splits evenly
+ * between members
+ */
+static unsigned long long round_size_to_mb(unsigned long long size, unsigned int
+                                          disk_count)
+{
+       size /= disk_count;
+       size = (size >> SECT_PER_MB_SHIFT) << SECT_PER_MB_SHIFT;
+       size *= disk_count;
+
+       return size;
+}
+
 /* try to determine how much space is reserved for metadata from
  * the last get_extents() entry on the smallest active disk,
  * otherwise fallback to the default
@@ -1401,7 +1415,6 @@ static int is_gen_migration(struct imsm_dev *dev);
 
 #define IMSM_4K_DIV 8
 
-#ifndef MDASSEMBLE
 static __u64 blocks_per_migr_unit(struct intel_super *super,
                                  struct imsm_dev *dev);
 
@@ -1676,7 +1689,6 @@ void examine_migr_rec_imsm(struct intel_super *super)
                break;
        }
 }
-#endif /* MDASSEMBLE */
 
 void convert_from_4k_imsm_migr_rec(struct intel_super *super)
 {
@@ -1836,7 +1848,6 @@ static int imsm_check_attributes(__u32 attributes)
        return ret_val;
 }
 
-#ifndef MDASSEMBLE
 static void getinfo_super_imsm(struct supertype *st, struct mdinfo *info, char *map);
 
 static void examine_super_imsm(struct supertype *st, char *homehost)
@@ -2550,8 +2561,6 @@ static int export_detail_platform_imsm(int verbose, char *controller_path)
        return result;
 }
 
-#endif
-
 static int match_home_imsm(struct supertype *st, char *homehost)
 {
        /* the imsm metadata format does not specify any host
@@ -2962,7 +2971,6 @@ out:
        return retval;
 }
 
-#ifndef MDASSEMBLE
 /*******************************************************************************
  * function: imsm_create_metadata_checkpoint_update
  * Description: It creates update for checkpoint change.
@@ -3103,7 +3111,6 @@ static int write_imsm_migr_rec(struct supertype *st)
                close(fd);
        return retval;
 }
-#endif /* MDASSEMBLE */
 
 /* spare/missing disks activations are not allowe when
  * array/container performs reshape operation, because
@@ -3323,11 +3330,10 @@ static void getinfo_super_imsm_volume(struct supertype *st, struct mdinfo *info,
                        if (used_disks > 0) {
                                array_blocks = blocks_per_member(map) *
                                        used_disks;
-                               /* round array size down to closest MB
-                                */
-                               info->custom_array_size = (array_blocks
-                                               >> SECT_PER_MB_SHIFT)
-                                               << SECT_PER_MB_SHIFT;
+                               info->custom_array_size =
+                                       round_size_to_mb(array_blocks,
+                                                        used_disks);
+
                        }
                }
                case MIGR_VERIFY:
@@ -3375,7 +3381,6 @@ static __u8 imsm_check_degraded(struct intel_super *super, struct imsm_dev *dev,
 static int imsm_count_failed(struct intel_super *super, struct imsm_dev *dev,
                             int look_in_map);
 
-#ifndef MDASSEMBLE
 static void manage_second_map(struct intel_super *super, struct imsm_dev *dev)
 {
        if (is_gen_migration(dev)) {
@@ -3391,7 +3396,6 @@ static void manage_second_map(struct intel_super *super, struct imsm_dev *dev)
                }
        }
 }
-#endif
 
 static struct imsm_disk *get_imsm_missing(struct intel_super *super, __u8 index)
 {
@@ -3973,7 +3977,6 @@ load_imsm_disk(int fd, struct intel_super *super, char *devname, int keep_fd)
        return 0;
 }
 
-#ifndef MDASSEMBLE
 /* When migrating map0 contains the 'destination' state while map1
  * contains the current state.  When not migrating map0 contains the
  * current state.  This routine assumes that map[0].map_state is set to
@@ -4061,7 +4064,6 @@ static void end_migration(struct imsm_dev *dev, struct intel_super *super,
        dev->vol.curr_migr_unit = 0;
        map->map_state = map_state;
 }
-#endif
 
 static int parse_raid_devices(struct intel_super *super)
 {
@@ -4507,7 +4509,6 @@ static int find_missing(struct intel_super *super)
        return 0;
 }
 
-#ifndef MDASSEMBLE
 static struct intel_disk *disk_list_get(__u8 *serial, struct intel_disk *disk_list)
 {
        struct intel_disk *idisk = disk_list;
@@ -5045,7 +5046,6 @@ static int load_container_imsm(struct supertype *st, int fd, char *devname)
 {
        return load_super_imsm_all(st, fd, &st->sb, devname, NULL, 1);
 }
-#endif
 
 static int load_super_imsm(struct supertype *st, int fd, char *devname)
 {
@@ -5234,6 +5234,8 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info,
        unsigned long long array_blocks;
        size_t size_old, size_new;
        unsigned long long num_data_stripes;
+       unsigned int data_disks;
+       unsigned long long size_per_member;
 
        if (super->orom && mpb->num_raid_devs >= super->orom->vpa) {
                pr_err("This imsm-container already has the maximum of %d volumes\n", super->orom->vpa);
@@ -5310,9 +5312,11 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info,
        strncpy((char *) dev->volume, name, MAX_RAID_SERIAL_LEN);
        array_blocks = calc_array_size(info->level, info->raid_disks,
                                               info->layout, info->chunk_size,
-                                              s->size * 2);
-       /* round array size down to closest MB */
-       array_blocks = (array_blocks >> SECT_PER_MB_SHIFT) << SECT_PER_MB_SHIFT;
+                                              s->size * BLOCKS_PER_KB);
+       data_disks = get_data_disks(info->level, info->layout,
+                                   info->raid_disks);
+       array_blocks = round_size_to_mb(array_blocks, data_disks);
+       size_per_member = array_blocks / data_disks;
 
        dev->size_low = __cpu_to_le32((__u32) array_blocks);
        dev->size_high = __cpu_to_le32((__u32) (array_blocks >> 32));
@@ -5324,7 +5328,9 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info,
        vol->curr_migr_unit = 0;
        map = get_imsm_map(dev, MAP_0);
        set_pba_of_lba0(map, super->create_offset);
-       set_blocks_per_member(map, info_to_blocks_per_member(info, s->size));
+       set_blocks_per_member(map, info_to_blocks_per_member(info,
+                                                            size_per_member /
+                                                            BLOCKS_PER_KB));
        map->blocks_per_strip = __cpu_to_le16(info_to_blocks_per_strip(info));
        map->failed_disk_num = ~0;
        if (info->level > 0)
@@ -5352,7 +5358,7 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info,
                map->num_domains = 1;
 
        /* info->size is only int so use the 'size' parameter instead */
-       num_data_stripes = (s->size * 2) / info_to_blocks_per_strip(info);
+       num_data_stripes = size_per_member / info_to_blocks_per_strip(info);
        num_data_stripes /= map->num_domains;
        set_num_data_stripes(map, num_data_stripes);
 
@@ -5456,7 +5462,6 @@ static int init_super_imsm(struct supertype *st, mdu_array_info_t *info,
        return 1;
 }
 
-#ifndef MDASSEMBLE
 static int add_to_super_imsm_volume(struct supertype *st, mdu_disk_info_t *dk,
                                     int fd, char *devname)
 {
@@ -6001,7 +6006,6 @@ static int mgmt_disk(struct supertype *st)
 
        return 0;
 }
-#endif
 
 __u32 crc32c_le(__u32 crc, unsigned char const *p, size_t len);
 
@@ -6109,8 +6113,6 @@ out:
        return ret;
 }
 
-#ifndef MDASSEMBLE
-
 static int write_init_ppl_imsm_all(struct supertype *st, struct mdinfo *info)
 {
        struct intel_super *super = st->sb;
@@ -6172,7 +6174,6 @@ static int write_init_super_imsm(struct supertype *st)
 
        return rv;
 }
-#endif
 
 static int store_super_imsm(struct supertype *st, int fd)
 {
@@ -6182,16 +6183,11 @@ static int store_super_imsm(struct supertype *st, int fd)
        if (!mpb)
                return 1;
 
-#ifndef MDASSEMBLE
        if (super->sector_size == 4096)
                convert_to_4k(super);
        return store_imsm_mpb(fd, mpb);
-#else
-       return 1;
-#endif
 }
 
-#ifndef MDASSEMBLE
 static int validate_geometry_imsm_container(struct supertype *st, int level,
                                            int layout, int raiddisks, int chunk,
                                            unsigned long long size,
@@ -7373,12 +7369,39 @@ static int update_subarray_imsm(struct supertype *st, char *subarray,
                        }
                        super->updates_pending++;
                }
+       } else if (strcmp(update, "ppl") == 0 ||
+                  strcmp(update, "no-ppl") == 0) {
+               int new_policy;
+               char *ep;
+               int vol = strtoul(subarray, &ep, 10);
+
+               if (*ep != '\0' || vol >= super->anchor->num_raid_devs)
+                       return 2;
+
+               if (strcmp(update, "ppl") == 0)
+                       new_policy = RWH_DISTRIBUTED;
+               else
+                       new_policy = RWH_OFF;
+
+               if (st->update_tail) {
+                       struct imsm_update_rwh_policy *u = xmalloc(sizeof(*u));
+
+                       u->type = update_rwh_policy;
+                       u->dev_idx = vol;
+                       u->new_policy = new_policy;
+                       append_metadata_update(st, u, sizeof(*u));
+               } else {
+                       struct imsm_dev *dev;
+
+                       dev = get_imsm_dev(super, vol);
+                       dev->rwh_policy = new_policy;
+                       super->updates_pending++;
+               }
        } else
                return 2;
 
        return 0;
 }
-#endif /* MDASSEMBLE */
 
 static int is_gen_migration(struct imsm_dev *dev)
 {
@@ -7412,7 +7435,6 @@ static int is_rebuilding(struct imsm_dev *dev)
                return 0;
 }
 
-#ifndef MDASSEMBLE
 static int is_initializing(struct imsm_dev *dev)
 {
        struct imsm_map *migr_map;
@@ -7430,7 +7452,6 @@ static int is_initializing(struct imsm_dev *dev)
 
        return 0;
 }
-#endif
 
 static void update_recovery_start(struct intel_super *super,
                                        struct imsm_dev *dev,
@@ -7464,9 +7485,7 @@ static void update_recovery_start(struct intel_super *super,
        rebuild->recovery_start = units * blocks_per_migr_unit(super, dev);
 }
 
-#ifndef MDASSEMBLE
 static int recover_backup_imsm(struct supertype *st, struct mdinfo *info);
-#endif
 
 static struct mdinfo *container_content_imsm(struct supertype *st, char *subarray)
 {
@@ -7505,9 +7524,7 @@ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarra
                struct imsm_map *map2;
                struct mdinfo *this;
                int slot;
-#ifndef MDASSEMBLE
                int chunk;
-#endif
                char *ep;
 
                if (subarray &&
@@ -7536,7 +7553,6 @@ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarra
                super->current_vol = i;
                getinfo_super_imsm_volume(st, this, NULL);
                this->next = rest;
-#ifndef MDASSEMBLE
                chunk = __le16_to_cpu(map->blocks_per_strip) >> 1;
                /* mdadm does not support all metadata features- set the bit in all arrays state */
                if (!validate_geometry_imsm_orom(super,
@@ -7551,7 +7567,6 @@ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarra
                          (1<<MD_SB_BLOCK_CONTAINER_RESHAPE) |
                          (1<<MD_SB_BLOCK_VOLUME);
                }
-#endif
 
                /* if array has bad blocks, set suitable bit in all arrays state */
                if (sb_errors)
@@ -7642,11 +7657,9 @@ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarra
                update_recovery_start(super, dev, this);
                this->array.spare_disks += spare_disks;
 
-#ifndef MDASSEMBLE
                /* check for reshape */
                if (this->reshape_active == 1)
                        recover_backup_imsm(st, this);
-#endif
                rest = this;
        }
 
@@ -7776,7 +7789,6 @@ static int imsm_count_failed(struct intel_super *super, struct imsm_dev *dev,
        return failed;
 }
 
-#ifndef MDASSEMBLE
 static int imsm_open_new(struct supertype *c, struct active_array *a,
                         char *inst)
 {
@@ -7946,9 +7958,7 @@ static unsigned long long imsm_set_array_size(struct imsm_dev *dev,
                array_blocks = new_size;
        }
 
-       /* round array size down to closest MB
-        */
-       array_blocks = (array_blocks >> SECT_PER_MB_SHIFT) << SECT_PER_MB_SHIFT;
+       array_blocks = round_size_to_mb(array_blocks, used_disks);
        dev->size_low = __cpu_to_le32((__u32)array_blocks);
        dev->size_high = __cpu_to_le32((__u32)(array_blocks >> 32));
 
@@ -8061,11 +8071,9 @@ static int imsm_set_array_state(struct active_array *a, int consistent)
                                        array_blocks =
                                                blocks_per_member(map) *
                                                used_disks;
-                                       /* round array size down to closest MB
-                                        */
-                                       array_blocks = (array_blocks
-                                                       >> SECT_PER_MB_SHIFT)
-                                               << SECT_PER_MB_SHIFT;
+                                       array_blocks =
+                                               round_size_to_mb(array_blocks,
+                                                                used_disks);
                                        a->info.custom_array_size = array_blocks;
                                        /* encourage manager to update array
                                         * size
@@ -9599,6 +9607,21 @@ static void imsm_process_update(struct supertype *st,
        }
        case update_prealloc_badblocks_mem:
                break;
+       case update_rwh_policy: {
+               struct imsm_update_rwh_policy *u = (void *)update->buf;
+               int target = u->dev_idx;
+               struct imsm_dev *dev = get_imsm_dev(super, target);
+               if (!dev) {
+                       dprintf("could not find subarray-%d\n", target);
+                       break;
+               }
+
+               if (dev->rwh_policy != u->new_policy) {
+                       dev->rwh_policy = u->new_policy;
+                       super->updates_pending++;
+               }
+               break;
+       }
        default:
                pr_err("error: unsuported process update type:(type: %d)\n",    type);
        }
@@ -9844,6 +9867,11 @@ static int imsm_prepare_update(struct supertype *st,
                super->extra_space += sizeof(struct bbm_log) -
                        get_imsm_bbm_log_size(super->bbm_log);
                break;
+       case update_rwh_policy: {
+               if (update->len < (int)sizeof(struct imsm_update_rwh_policy))
+                       return 0;
+               break;
+       }
        default:
                return 0;
        }
@@ -9932,7 +9960,6 @@ static void imsm_delete(struct intel_super *super, struct dl **dlp, unsigned ind
                __free_imsm_disk(dl);
        }
 }
-#endif /* MDASSEMBLE */
 
 static void close_targets(int *targets, int new_disks)
 {
@@ -10135,7 +10162,7 @@ int validate_container_imsm(struct mdinfo *info)
 
        return 0;
 }
-#ifndef MDASSEMBLE
+
 /*******************************************************************************
 * Function:   imsm_record_badblock
 * Description: This routine stores new bad block record in BBM log
@@ -11781,10 +11808,7 @@ abort:
        return ret_val;
 }
 
-#endif /* MDASSEMBLE */
-
 struct superswitch super_imsm = {
-#ifndef        MDASSEMBLE
        .examine_super  = examine_super_imsm,
        .brief_examine_super = brief_examine_super_imsm,
        .brief_examine_subarrays = brief_examine_subarrays_imsm,
@@ -11807,7 +11831,6 @@ struct superswitch super_imsm = {
        .recover_backup = recover_backup_imsm,
        .copy_metadata = copy_metadata_imsm,
        .examine_badblocks = examine_badblocks_imsm,
-#endif
        .match_home     = match_home_imsm,
        .uuid_from_super= uuid_from_super_imsm,
        .getinfo_super  = getinfo_super_imsm,
@@ -11833,7 +11856,6 @@ struct superswitch super_imsm = {
        .external       = 1,
        .name = "imsm",
 
-#ifndef MDASSEMBLE
 /* for mdmon */
        .open_new       = imsm_open_new,
        .set_array_state= imsm_set_array_state,
@@ -11845,5 +11867,4 @@ struct superswitch super_imsm = {
        .record_bad_block = imsm_record_badblock,
        .clear_bad_block  = imsm_clear_badblock,
        .get_bad_blocks   = imsm_get_badblocks,
-#endif /* MDASSEMBLE */
 };